Finding world location of LineSegment Start and end points

Ahh, so it is rotating about the world Z axis. That’s not what I’m trying to do.



I am still confused by this. There is a good way of doing this, I just haven’t figured it out yet. So again, the application is making a sonar sensor on the vehicle using rays. I would also like a visual representation of the path of the ray. I have a couple of ideas of how to do this:


  1. For each cycle of the updateLoop, I would have to create the “sonar sensor” object that is made up of “Line” objects. I prefer to use my Line class as it allows me to set the line color. I would eventually like it to change the color as well if the ray hits an object within the length of that line (effectively showing a sonar “hit”)

    To create the sonar object, I would draw my lines along the world UNIT_X to the length they need to be. Then rotate the lines upward (about the world UNIT_Z) to the degree of the spread of the sensor. Then I would make a cone using lines drawn in this method, but then again rotated about the UNIT_X by an increment until I have a full 360 degrees of lines. This effectively makes a cone shape. Once I have the entire sonar sensor drawn this way based on the world UNIT_X and UNIT_Z, I would then translate the sonar object to the front of the vehicle and calculate where to place it, then rotate it appropriately. This would have to happen each cycle of the update loop. Once every physicsTick, I could get the localToWorld of each line’s start and endpoint and cast a Ray along the path of each line. I think this would take way too long, especially if I have a lot of lines or if I have more than 1 sensor on the vehicle.


  2. Create the sonar sensor as stated above just once in the SimpleInit, and attach it as a child to the vehicle. Once every PhysicsTick I would then somehow access the start and endpoints of each line (using localToWorld) and cast a Ray along the path of that line. This takes much less time than the first method, but I’m not sure I will be able to access the start and endpoints of the lines.



    For each method above I will only be casting rays if I am within range of something. This is accomplished by attaching a spherical ghostNode to the vehicle with a radius of the maximum sensing distance of the sonar. If the ghostNode overlaps any collidable, then it will go about either method 1 or 2 above to see if it is in front of the sonar sensor(s).



    Now I don’t know how to get the localToWorld of the start and endpoints of the lines once they are moved or rotated. If I just use the start and endpoints I used to create them, this will not take into consideration the translations and rotations of the vehicle would it?



    Am I going about this all wrong? Is there a better method? Any suggestions on how to get the start and endpoints of the lines after attaching them to the vehicle?
@morrowsend said:
Ahh, so it is rotating about the world Z axis. That's not what I'm trying to do.


Then I'm confused... because rotating around the Z axis is precisely what your code says it is doing:
[java]
Vector3f sideVctr = Vector3f.UNIT_Z; //Line perpendicular to the Forward vector (in the simple case)

//Rotate about Z by theta (45 degrees)
Quaternion thetaQuat = new Quaternion();
thetaQuat.fromAngleAxis((theta * FastMath.DEG_TO_RAD), sideVctr);
[/java]

Even the comment says "rotate about Z".

@morrowsend said:
Now I don’t know how to get the localToWorld of the start and endpoints of the lines once they are moved or rotated. If I just use the start and endpoints I used to create them, this will not take into consideration the translations and rotations of the vehicle would it?


I'm so confused since the answers you were getting were translated and rotated. And would have taken into consideration any rotations and translations between the geometry and the root node.

I'm totally lost now.

And note: it’s not the “world Z axis” it’s the parent’s Z axis.

@pspeed said:
Then I'm confused... because rotating around the Z axis is precisely what your code says it is doing:


I was trying to do it with a simple case, hence the hardcoded UNIT_Z there. I would like to be able to replace that Z axis with a vector perpendicular.


I'm so confused since the answers you were getting were translated and rotated. And would have taken into consideration any rotations and translations between the geometry and the root node.

I'm totally lost now.


I'm sorry. It is very hard to explain, but easy to see. Just watch a few seconds of this video: http://www.youtube.com/watch?feature=player_detailpage&list=UU5FaWsv86tedI3jBcMigp5g&v=JRd9PH6I9PY#t=300s


I want to make a sonar sensors like that. There will be a visible line showing where the ray is being cast. That is it. I want it attached to a vehicle( possibly more than 1 at a time) I have something that somewhat works if the vehicle never leaves the X-Z plane, making it basically 2D. The current implementation will not work in 3D.

The problem is that to do something like those sensors, I will need to keep track of the start point and end points of each line in the sonar sensor. The sonar sensor itself will be attached to the vehicle. The spatial tree looks like this:
Vehicle --> SonarSensorObject-->LineObject-->GeometryOfLine

All of my code posted so far has been attempting to draw that cone shape. My current method only works if I draw the cone at the origin of the world reference.

(You can skip this next part as it describes how I am doing it...) I currently do it by drawing a straight line along X, then rotating it about Z first to get the span the sonar sensor can see. This line represents the side of the cone. I will then do this with 7 other lines (to make 8 total). Each subsequent line is currently rotated again about the X axis by 45 degrees (360/8) to move it about the circumference of the cone I am trying to create. The video below is my code drawing the cone shape which is only Lines, no Rays.

http://www.youtube.com/watch?v=xHFQVV3JW84

Now if I attach this object to the vehicle and drive the vehicle around, the cone moves too, which is great. The problem is that I now need to know the start and endpoint of each line in the cone so I can cast a ray along the same path at each physicsTick.

My ultimate goal would be to create an object called RayLine which I could use to create the Sonar Sensor object that is attached to the vehicle. Every physicsTick It would automatically update the start point and direction vector of each ray (by looking at the current localToWorld values of the RayLine object) and return the collisions. That way everything would be nicely abstracted and I could add multiple SonarSensor objects to the vehicle if I wanted to (which I do).

Make sense? So my questions are the following:
1) How might I find the start and endpoints (using the world reference) of a line that is a Geometry attached to a SonarSensor Node which is in turn attached to a vehicle? (This is partially why I have made my own Line object.) The problem here is that I have to attach the line to the sonarNode, so I have "class Line extends Geometry" and in doing so, I loose the ability to access the start and endpoint variables. Maybe this is because of the way the Line is written? The only way I have figured out how to access those variables is to create an ArrayList of LineObjects, then to access each one separately. This will return the start as (0,0,0) and endpoint as (1,0,0) for instance, which is useless because I have already rotated the lines twice to create the cone shape. Those start and endpoints are incorrect after the rotations.
2) Is there a better way?

I really appreciate your help.

Before I go any further…



From you video, are you trying to find the rays (in world space) of all of the lines in the cone… or just the center of the cone?

I’m trying to find the start and endpoints of each line in the world space so I can create a ray. The video shows all the lines having the same start point, 0,0,0. When the lines are attached to the vehicle, it could be anywhere. The same with the endpoints except the endpoints will not all be equal to one another obviously.

Do not create your own Geometry class. It is only confusing the heck out of you and is not helpful.



You may want to read this about 50 times or so:https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:scenegraph_for_dummies



:slight_smile:



But seriously, take a step waaaaaaay back.



Create a Node that will be your vehicle.



Create a Geometry (regular plain vanilla geometry) as a child of that to be one your sonar rays. Give it a com.jme3.scene.shape.Line as its mesh. Position and rotate that Geometry in vehicle space as needed… Much the way you have in your example. But let’s just start with one. Rotating the geometry where you want it is the hardest part in all of this. It seems to me like you want two rotations… one rotating it up to the cone and then another rotating it around the cone. You could also opt to just put the far endpoint of the line right where you want it in the first place.



At any rate, once you get it displaying the way it’s supposed to using that approach then everything is right. Don’t do any hacks. Use stock JME nodes and mesh stuff and simple translations and rotations.



Then…



Use localToWorld( ((Line)geom.getMesh()).getEnd(), null ) to find its far endpoint in world space.



That will work no matter where you move the vehicle node or which way you move it.



That will also give you the answer in your last example that I said was right. So if it’s not right then you will need to explain better why it isn’t right.

ok, awesome! Thanks for the input! I’ll study that screengraph for dummies some more and give if another shot from scratch so I can keep things straight. You’re right, I’m just confusing myself with the “making my own geometry” stuff. I appreciate the help and I’ll update this thread with my results.

Good luck! :slight_smile:

OK, Started over, but I’m still getting unexpected values for the endpoint here.

I begin with a line that is 5 units long, then rotate this by 30 degrees. This creates a 30-60-90 triangle with a hypotenuse of |5|. That means the endpoint of the line should reside at (4,3,0). When I print the localToWorld of this action, I get a different position, I get (4.330127, 2.5, 0). I don’t see what I have done wrong here.



Here is the code, the output reads "Start = (0.0, 0.0, 0.0) end = (4.330127, 2.5, 0.0) " :

[java]//create vehicle

Vector3f halfExtents = new Vector3f(0.25f, 0.25f, 0.25f);

Material material = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

material.setTexture(“ColorMap”, assetManager.loadTexture(“Interface/Logo/Monkey.jpg”));

Box box = new Box(halfExtents.x, halfExtents.y, halfExtents.z); //half extents

Geometry boxGeometry = new Geometry(“Box”, box);

boxGeometry.setMaterial(material);

boxGeometry.setLocalTranslation(0, 0, 0);



Node vehicle = new Node();

vehicle.attachChild(boxGeometry);

rootNode.attachChild(vehicle);



//Create line Geom

Line line = new Line(new Vector3f(0, 0, 0), new Vector3f(5, 0, 0));

Geometry lineGeom = new Geometry(“lineMesh”, line);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“m_Color”, ColorRGBA.Magenta);

lineGeom.setMaterial(mat);



// Rotate line by theta to get span of sensor

Quaternion theta = new Quaternion();

theta.fromAngleAxis((30 * FastMath.DEG_TO_RAD), Vector3f.UNIT_Z);

lineGeom.rotate(theta);



//rootNode.attachChild(lineGeom); //attach line to root node

vehicle.attachChild(lineGeom); //attach line to vehicle



//If I rotate the line of length 5 by 30 degrees, the resulting endpoint should be (4,3,0)

System.out.println("Start = " + lineGeom.localToWorld(((Line) lineGeom.getMesh()).getStart(), null) + " end = " + lineGeom.localToWorld(((Line) lineGeom.getMesh()).getEnd(), null));

[/java]

Your napkin math is incorrect. A 30-60-90 triangle is not a 3/4/5 triangle.



The ‘x’ side will be cos(30) * 5 and the ‘y’ side will be sin(30) * 5 which are 4.33 and 2.5 respectively. So the values are correct.

And for the record, the small angle of a 3/4/5 triangle is ~36.8 degrees or so.

Bah! good catch, thanks again. It has been years since I’ve done even basic trig stuff. I used 3/4/5 because that stuck in my mind as an easy 90-degree triangle to calculate and just assumed that was 30/60/90. In normal life, I’m usually quick with stuff, but when it comes to this project I come off like a simpleton on these forums. I have to start paying much more attention to details.



Thanks again for all your help!