com.jme.math.Line.distance(Vector3f) broken?

When I run this I get 3.0!!!  I think I should get 0.0.



        com.jme.math.Line l2 = new com.jme.math.Line(

              new Vector3f(0f,0f,0f), new Vector3f(0f,2f,0f));

        System.err.println(l2.distance(new Vector3f(0f,1f,0f)));



Do I not understand the distance function? Is there a way to see if a Vector3f is on the line before I call distance?



I'm new here…should i have posted this somewhere else?



Thanks,

Tim

Oh yes: jME 2.0 on Windows XP using Sun's JVM



java version "1.6.0_15"

Java™ SE Runtime Environment (build 1.6.0_15-b03)

Java HotSpot™ Client VM (build 14.1-b02, mixed mode, sharing)

perry2of5 said:

When I run this I get 3.0!!!!  I think I should get 0.0.


It should be a distance of one if you're calculating from either the origin or the end point, no?

It's impossible to get the distance between many points and a single point, one point would have to be chosen from the line..  I'm frankly confused as to why the source function is manipulating scalars:


public float distanceSquared(Vector3f point) {
      point.subtract(origin, compVec1);
      float lineParameter = direction.dot(compVec1);
      origin.add(direction.mult(lineParameter, compVec2), compVec2);
      compVec2.subtract(point, compVec1);
      return compVec1.lengthSquared();
    }
   
    public float distance(Vector3f point) {
    return FastMath.sqrt(distanceSquared(point));
    }


Now you've got me interested  :x

I was thinking this would give me the distance from the point to the nearest point on the line. In this case, the point is on the line so the answer would be 0.0. 



This would be similar to the psuedoDistance funtion on a plane. http://www.jmonkeyengine.com/doc/com/jme/math/Plane.html#pseudoDistance(com.jme.math.Vector3f)



I'm working on getting subversion working with my eclipse so I can dive into this… Any help would be appreciated.



Incidently, the math is solved many places such as http://solvedproblems.wordpress.com/2008/03/11/distance-of-a-point-from-a-line-in-3d/  Just google "distance from line to a point 3d" or click this http://tinyurl.com/ygsff9w




Mmmm… hold your horses. The method seems to work well if you provide the direction vector in normalized form:



         Line l2 = new Line(Vector3f.ZERO, new Vector3f(0f,  1.0f  ,0f));
         System.err.println(l2.distance(new Vector3f(0f,1f,0f)));



(Just in case, note that the line is infinite: constructor arguments are origin and direction).

Also:


Is there a way to see if a Vector3f is on the line before I call distance?


I think there's no way to really know if a point belongs to a line. You would need to include some error margin variable into the algorithm for it to work. That'd be something like line.distance(point) <  error_margin.

I hope that helps.

Thanks jjmontes!  Just for anybody else wondering, this does the trick:



com.jme.math.Line l2 = new com.jme.math.Line(

new Vector3f(0f,0f,0f), new Vector3f(0f,2f,0f).normalize());

System.err.println(l2.distance(new Vector3f(0f,1f,0f)));



Perhaps it is worth altering the line class to call .normalize() on the direction vector passed in. If enough people agree maybe I'll submit an enhancement request.  I wish I'd realized I needed to normalize the vector; I wrote my own 3d geometry calculation classes last night after I failed to see what was wrong here.



Anybody else run into this? Or did I just fail to RTFM?

My suggestion would be just to add a comment to the javadoc for the constructor and the setter indicating that the vector needs to be normalized. This keeps the computation from being necessary when you know the the vector you are passing is normalized already. It's not a huge deal, but when every frame counts, unnecessary floating point ops can make a difference.



Just a thought, but I'm far from the most experienced game developer ever… feel free to correct my thinking here.

I don't think direction should be normalized inside the Line, as this would be too expensive and unnecessary in many ocassions. It's left up to the programmer to decide. I think this is a common approach along JME, so remember to always check if a direction should be normalized when you supply other method with it.



So I agree with despotes, whis should better be documented. I'm working on the Javadoc, will post to the Contribution Depot.



Also, in your example, using normalizeLocal() would be better:



new Vector3f(0f,2f,0f).normalizeLocal()



That will avoid one object creation.

Documentation suggestions posted to http://www.jmonkeyengine.com/forum/index.php?topic=12564.0. Comments go there.

Thank you kindly!