Let me first define my problem,
I am working on an indoor navigation problem. So I constructed a graph to simulate possible paths. I can easily calculate the shortest path with Dijkstra and draw it on a map. So far, so good.
But this is not enough,
I need to give instruction to user to navigate him.
For example:
"Turn Right"
"Turn Left"
"Go on from the left"
To give these kind of instructions I need to know which path is on the left and which path is on the right.
And here is what I have to solve this:
1. A undirected weighted graph
2. The shortest path which contains vertices and edges
3. X and Y Coordinates of each vertices
By the way I will do this in .Net by using beacon technology.
Do you know how to separate left and right edges so I can give direction messages to user?
Thanks.
The easiest way I can think of is to take the cross product of the vector representing the direction the player is facing/traveling and the vector representing direction you want the player to go in. Whether the player must turn left or right depends on whether the result's Y-coordinate is positive or negative, but which is which depends on the handedness of the coordinate system. I would just pick one and try it. You have a 50% of being right, and it's easy to reverse if you're wrong.
Edit:
Here we see that a×b points up when a is to the right of b. However, we also see that -a×b points down. So, if a were pointing in the opposite direction—to the left—then the cross product would point down.
The dot product approach does not work in two dimensions. For this case you want to use the sign of the determinant of the matrix [A B], where A and B are your column vectors. A pseudo-code would be
c=sign(det([A B]))
Here, if c>0 is means that B is to the left. This will switch depending on the order of A and B in your matrix.
Related
I am trying to understand how to manually generate objects.
I have a mesh, part of which I delete and create a new geometry in its place. I have information about the normals of deleted vertices. On the basis of which I have to build new faces (in a different size and quantity) looking in the same direction.
But I don’t understand how to choose the correct winding. It sounds easy when the lessons talk about CCW winding in screen space. But what if I have a bunch of almost chaotic points in the model space? How then to determine this CCW, which axis is used for this? I suggest that the nearest old normals might help. But what is the cheapest method to determine the correct order?
It turned out to be easier than I thought. It is necessary to find the cross product of the first two vectors from the vertices of a triangle, then find the dot of the resulting vector and the normal vector, if the result is negative, then during generation it is necessary to change the order of vertices.
A short introduction:
I have a body that is expressed by the outer-surface, given in STL form (set of triangular elements and their outside-pointing normal vector).
I'm trying to detect if a point given by coordinates is inside or outside the body.
The problem:
How do I find the nearest element to a given point?
More specifically, say you have found the nearest vertex to the point and this vertex is shared by two (or more) elements. Which is is the "nearest" one?
Note that the end result is determining if the point is inside or outside the body. A simple normal distance (dot product with the normal) does not solve the problem and can lead to ambiguous result based on which of the elements, sharing the node is selected.
Using the centroid of the element is also problematic.
Any suggestions, ideas (especially from people who have been involved in this issue before) are most welcomed!
EDIT:
I'll make the issue slightly harder. Say there's an open surface (but it covers the whole domain so that every point is on one of two sides of the surface, either in or out, based on the direction relative to the normal.
This also needs to be answered using the same approach.
EDIT2:
Answer was found!
Hope this helps!
The problem was answered with a variation of the ray-intersection method. 1. Find the nearest vertex, using the L2 norm (squared). 2. Consider the elements which share the vertex. It is recommended to have a connectivity list and not map them every time. 3. Cast a ray is cast from the interest point to the centroid of the first element. 4. Check among the elements in <2> which intersect the ray and select the one with the shortest intersection distance 5. Use the dot product of the intersection vector with the element normal (negative sign = outside, else inside)
(This was added to the question post itself)
I have a complicated problem and it involves an understanding of Maths I'm not confident with.
Some slight context may help. I'm building a 3D train simulator for children and it will run in the browser using WebGL. I'm trying to create a network of points to place the track assets (see image) and provide reference for the train to move along.
To help explain my problem I have created a visual representation as I am a designer who can script and not really a programmer or a mathematician:
Basically, I have 3 shapes (Figs. A, B & C) and although they have width, can be represented as a straight line for A and curves (B & C). Curves B & C are derived (bend modified) from A so are all the same length (l) which is 112. The curves (B & C) each have a radius (r) of 285.5 and the (a) angle they were bent at was 22.5°.
Each shape (A, B & C) has a registration point (start point) illustrated by the centre of the green boxes attached to each of them.
What I am trying to do is create a network of "track" starting at 0, 0 (using standard Cartesian coordinates).
My problem is where to place the next element after a curve. If it were straight track then there is no problem as I can use the length as a constant offset along the y axis but that would be boring so I need to add curves.
Fig. D. demonstrates an example of a possible track layout but please understand that I am not looking for a static answer (based on where everything is positioned in the image), I need a formula that can be applied no matter how I configure the track.
Using Fig. D. I tried to work out where to place the second curved element after the first one. I used the formula for plotting a point of the circumference of a circle given its centre coordinates and radius (Fig. E.).
I had point 1 as that was simply a case of setting the length (y position) of the straight line. I could easily work out the centre of the circle because that's just the offset y position, the offset of the radius (r) (x position) and the angle (a) which is always 22.5° (which, incidentally, was converted to Radians as per formula requirements).
After passing the values through the formula I didn't get the correct result because the formula assumed I was working anti-clockwise starting at 3 o'clock so I had to deduct 180 from (a) and convert that to Radians to get the expected result.
That did work and if I wanted to create a 180° track curve I could use the same centre point and simply deducted 22.5° from the angle each time. Great. But I want a more dynamic track layout like in Figs. D & E.
So, how would I go about working point 5 in Fig. E. because that represents the centre point for that curve segment? I simply have no idea.
Also, as a bonus question, is this the correct way to be doing this or am I over-complicating things?
This problem is the only issue stopping me from building my game and, as you can appreciate, it is a bit of a biggie so I thank anyone for their contribution in advance.
As you build up the track, the position of the next piece of track to be placed needs to be relative to location and direction of the current end of the track.
I would store an (x,y) position and an angle a to indicate the current point (with x,y starting at 0, and a starting at pi/2 radians, which corresponds to straight up in the "anticlockwise from 3-o'clock" system).
Then construct
fx = cos(a);
fy = sin(a);
lx = -sin(a);
ly = cos(a);
which correspond to the x and y components of 'forward' and 'left' vectors relative to the direction we are currently facing. If we wanted to move our position one unit forward, we would increment (x,y) by (fx, fy).
In your case, the rule for placing a straight section of track is then:
x=x+112*fx
y=y+112*fy
The rule for placing a curve is slightly more complex. For a curve turning right, we need to move forward 112*sin(22.5°), then side-step right 112*(1-cos(22.5°), then turn clockwise by 22.5°. In code,
x=x+285.206*sin(22.5*pi/180)*fx // Move forward
y=y+285.206*sin(22.5*pi/180)*fy
x=x+285.206*(1-cos(22.5*pi/180))*(-lx) // Side-step right
y=y+285.206*(1-cos(22.5*pi/180))*(-ly)
a=a-22.5*pi/180 // Turn to face new direction
Turning left is just like turning right, but with a negative angle.
To place the subsequent pieces, just run this procedure again, calculating fx,fy, lx and ly with the now-updated value of a, and then incrementing x and y depending on what type of track piece is next.
There is one other point that you might consider; in my experience, building tracks which form closed loops with these sort of pieces usually works if you stick to making 90° turns or rather symmetric layouts. However, it's quite easy to make tracks which don't quite join up, and it's not obvious to see how they should be modified to allow them to join. Something to bear in mind perhaps if your program allows children to design their own layouts.
Point 5 is equidistant from 3 as 2, but in the opposite direction.
I am taking Computer Graphics course.In 3D,I have a point and a polygon and I want to determine this point is located above or below my polygon.Thanks for your replies,in advance.
If above or below the plane on which the polygon is resting will do, you can compare the dot product of the point onto the plane normal and that of any point on the plane. Or look at the sign of the dot product between the normal and a vector from a point on the plane to the point, if you prefer.
To check whether it is actually 'above' or 'below' in the sense of being directly above or below (ie, not off to the side somewhere) then do a point in polygon by projecting the whole thing into 2d along the normal and then a distance along normal test.
It depends on your definition of above and below, let me first talk about the easy case:
If you think of above/below in terms of a global direction (typically the y-axis or z-axis), just compare the values on that axis.
Ok, now the more difficult interpretation: On which side of the polygon is the point.
Unless it is complanar you cannot decide it for the polygon at once. So if it is non-complanar you have to tesselate it into triangles and decide for each of them.
For a triangle you can decide whether a point is above or below it (in 3D), first calculate the cross product of 2 vectors that make up the sides of the triangle; this will define a direction (= the definition of "above" and "below"), this depends on the order in which you use those 2 vectors so be careful. Then calculate the dot-product of the new vector (which is called the perpendicular of that triangle) and the difference-vector of the point-to-test and the triangle-base.
I am trying to animate an object, let's say its a car. I want it go from point
x1,y1,z1
to point x2,y2,z2 . It moves to those points, but it appears to be drifting rather than pointing in the direction of motion. So my question is: how can I solve this issue in my updateframe() event? Could you point me in the direction of some good resources?
Thanks.
First off how do you represent the road?
I recently done exactly this thing and I used Catmull-Rom splines for the road. To orient an object and make it follow the spline path you need to interpolate the current x,y,z position from a t that walks along the spline, then orient it along the Frenet Coordinates System or Frenet Frame for that particular position.
Basically for each point you need 3 vectors: the Tangent, the Normal, and the Binormal. The Tangent will be the actual direction you will like your object (car) to point at.
I choose Catmull-Rom because they are easy to deduct the tangents at any point - just make the (vector) difference between 2 other near points to the current one. (Say you are at t, pick t-epsilon and t+epsilon - with epsilon being a small enough constant).
For the other 2 vectors, you can use this iterative method - that is you start with a known set of vectors on one end, and you work a new set based on the previous one each updateframe() ).
You need to work out the initial orientation of the car, and the final orientation of the car at its destination, then interpolate between them to determine the orientation in between for the current timestep.
This article describes the mathematics behind doing the interpolation, as well as some other things to do with rotating objects that may be of use to you. gamasutra.com in general is an excellent resource for this sort of thing.
I think interpolating is giving the drift you are seeing.
You need to model the way steering works .. your update function should 1) move the car always in the direction of where it is pointing and 2) turn the car toward the current target .. one should not affect the other so that the turning will happen and complete more rapidly than the arriving.
In general terms, the direction the car is pointing is along its velocity vector, which is the first derivative of its position vector.
For example, if the car is going in a circle (of radius r) around the origin every n seconds then the x component of the car's position is given by:
x = r.sin(2πt/n)
and the x component of its velocity vector will be:
vx = dx/dt = r.(2π/n)cos(2πt/n)
Do this for all of the x, y and z components, normalize the resulting vector and you have your direction.
Always pointing the car toward the destination point is simple and cheap, but it won't work if the car is following a curved path. In which case you need to point the car along the tangent line at its current location (see other answers, above).
going from one position to another gives an object a velocity, a velocity is a vector, and normalising that vector will give you the direction vector of the motion that you can plug into a "look at" matrix, do the cross of the up with this vector to get the side and hey presto you have a full matrix for the direction control of the object in motion.