First of all I am having trouble with the concept of a mathematical Vector when being applied to a Vector3d. I understand a vector to be just like a line except it has a direction property.
Now, Vector3d only takes in 3 arguments (x,y,z) in its constructor. I assumed this to be because the vector initially is assumed to start at the origin and go through the designated point. How can we ever have a vector which does not intersect the origin if the only attributes contained in Vector3d are x,y,z?
For example, I am trying to program a function which calculates the distance between two points on a sphere:
//Returns the shortest distance between two points on a sphere
public static double getGreatCircleDistance(Point3d p1, Point3d p2){
Vector3d v1 = getVector(viewSphereOrigin, p1);
Vector3d v2 = getVector(viewSphereOrigin, p2);
v1.normalize();
v2.normalize();
return Math.acos(v1.dot(v2)*(viewSphereDiameter/2));
}
//Returns a vector through two given Points in 3d space
public static Vector3d getVector(Point3d start, Point3d terminal){
return new Vector3d(terminal.x-start.x, terminal.y-start.y, terminal.z-start.z);
}
I do not understand however how getVector() can return a vector which passes through the two given points. I researched how to obtain a vector connecting two points:
http://emweb.unl.edu/math/mathweb/vectors/vectors.html#vec6
however fundamentally I still do not understand this. Can someone clear up the logic behind Vector3d for me please and how it can represent an arbitrary vector in 3D space yet it only contains x,y,z?
Thanks!
A vector is not a line; it is an entity with a magnitude and a direction. What it does not have is location.
You can represent a vector as the line segment between any two points: the magnitude is the distance between the points, and the direction is given by the direction of the line. Every time the distance and direction of the line are the same you get the same vector.
Since a vector does not have a location, we can arbitrarily choose one of the points to be the origin. This way a triple «x,y,z» uniquely represent a vector with the direction of the line from the point (0,0,0) to the point (x,y,z). But you get the same vector also by picking the points (5,4,2) and (5+x, 4+y, 2+z), or any other two points that are at the same distance and direction from each other.
As I know Vector3D means a [x,y,z] starting from the origin. If you would like to store a vector in 3D space (called Ray) you should store two Vector3D:
1. the starting point and the end point of the vector
OR
2. the origin and the direction of the vector.
Related
This post is a reply to: 3D Ray-Quad intersection test in java
Because I can't yet comment.
My question is, how did they get:
A point M belongs to this plane iff it satisfies this equation: n . ( M - S1 ) = 0
How is the (dotProduct(n, (M - S1)) == 0) suppose to tell us that the ray intersects the quad?
In my opinion Wikipedia answers this question quite well: Wiki
In a manner analogous to the way lines in a two-dimensional space are described using a point-slope form for their equations, planes in a three dimensional space have a natural description using a point in the plane and a vector orthogonal to it (the normal vector) to indicate its "inclination".
Specifically, let r0 be the position vector of some point P0 = (x0,
y0, z0), and let n = (a, b, c) be a nonzero vector. The plane
determined by the point P0 and the vector n consists of those points
P, with position vector r, such that the vector drawn from P0 to P is
perpendicular to n. Recalling that two vectors are perpendicular if
and only if their dot product is zero, it follows that the desired
plane can be described as the set of all points r such that
With other words you have a normal vector of a plane and a vector created by a point of the plane and the point you are checking if it is on the plane. The dot-product tells you something about the angle between the two vector. Therefore if the vector is parallel to the plane, the point has to be on the plane.
Does anybody know how to find out if a set of coordinates are within a triangle for which you have the coordinates for. i know how to work out length of sides, area and perimeter, but i have no idea where to begin working out the whereabouts within the triangle of other points.
Any advice would be appreciated
You can create a Polygon object.
Polygon triangle = new Polygon();
Add the vertexes of your triangle with the addPoint(int x, int y) method.
And then, you just need to check if the set of coordinates is inside your triangle using contains(double x, double y) method.
Use the contains method of the Polygon class as documented here.
For a solution without using the Polygon-class:
Assume that you have giving three points A,B,C the vertices of your polygon. Let P be the point you want to check. First calculate the vectors representing the edges of your triangle. Let us call them AB, BC, CA. Also calculate the three vectors PA, PB, PC.
Now calculate the cross product between the first two of the vectors from above.
The cross product of the first pair gives you the sin(alpha), where alpha is the angle between AB and PA, multiplied with a vector pendenpicular to AB and PA. Ignore this vector because we are interested in the angle and take a look at the sine (in the case of 2D vectors you can imagine it as the vector standing perpendicular to your screen).
The sine can take values between (let's say for the ease) betwenn 0 and 2*Pi. It's 0 exactly at 0 and Pi. For every value in between the sine is positive and for every value between Pi and 2*Pi it's negative.
So let's say your Point p is on the left hand side of AB, so the sine would be positive.
By taking the cross product of each pair from above, you could easily guess that the point P is on the left hand side of each edge from the triangle. This just means that it has to be inside the triangle.
Of course this method can even be used from calculating whether a point P is in a polygon. Be aware of the fact, that this method only works if the sides of the polygon are directed.
This is a fairly remedial question. I have been looking at the documentation for the JTS DelaunayTriangulationBuilder and I am at a loss as to how to do what seems like it should be a simple thing. I wish to take a series of points, triangulate them, and then interpolate the Z value of a random point within that mesh. It's non-obvious from a cursory reading how to do this. Any ideas?
After you've loaded up the triangulation object, call getSubdivision() on it to get the triangulation. It uses a quad-edge data structure, which you'll need later. (It's easier to understand if you know what a half-edge or winged-edge representation is.) The resulting QuadEdgeSubdivision has a method locate that, given a coordinate, returns one of the edges of the enclosing triangle (as a quad-edge). Get its origin vertex with orig() and its destination vertex with dest(). Get another edge with oNext() Its destination vertex is the third vertex (also dPrev().origin() is the same vertex). Now that you have the three vertices, represent your test point as a Vertex and call interpolateZValue.
For example:
public static double
interpolateZ(DelaunayTriangulationBuilder triangulation,
Coordinate coordinate) {
QuadEdgeSubdivision quadEdgeSubdivision = triangulation.getSubdivision();
QuadEdge edge = quadEdgeSubdivision.locate(coordinate);
return new Vertex(coordinate.x, coordinate.y)
.interpolateZValue(edge.orig(), edge.dest(), edge.oNext().dest());
}
You're right, though. It's not obvious how to do this from reading their API.
I'm not familiar with JTS DelauneyTriangulationBuilder, but it sounds like you have a collection of points (x,y,z), and you are submitting the 2D (x,y) pairs to the triangulator. This gives you a planar triangulation of the (x,y) points, but also a mesh who's vertices are the original (x,y,z) points.
Once you have a triangulation, you wish to find the point (p,q,r) on the mesh that corresponds to the planar point (p,q). To do so, find the triangle T of the Delauney triangulation that contains (p,q). Find the barycentric coordinates of (p,q) relative to T, and use these to compute a weighted average r of the z values corresponding to the vertices of T. That weighted average is the Z value you're looking for. In other words, (p,q,r) is on the mesh.
I'm trying to write a 2D game in Java that uses the Separating Axis Theorem for collision detection. In order to resolve collisions between two polygons, I need to know the Minimum Translation Vector of the collision, and I need to know which direction it points relative to the polygons (so that I can give one polygon a penalty force along that direction and the other a penalty force in the opposite direction). For reference, I'm trying to implement the algorithm here.
I'd like to guarantee that if I call my collision detection function collide(Polygon polygon1, Polygon polygon2) and it detects a collision, the returned MTV will always point away from polygon1, toward polygon2. In order to do this, I need to guarantee that the separating axes that I generate, which are the normals of the polygon edges, always point away from the polygon that generated them. (That way, I know to negate any axis from polygon2 before using it as the MTV).
Unfortunately, it seems that whether or not the normal I generate for a polygon edge points towards the interior of the polygon or the exterior depends on whether the polygon's points are declared in clockwise or counterclockwise order. I'm using the algorithm described here to generate normals, and assuming that I pick (x, y) => (y, -x) for the "perpendicular" method, the resulting normals will only point away from the polygon if I iterate over the vertices in clockwise order.
Given that I can't force the client to declare the points of the polygon in clockwise order (I'm using java.awt.Polygon, which just exposes two arrays for x and y coordinates), is there a mathematical way to guarantee that the direction of the normal vectors I generate is toward the exterior of the polygon? I'm not very good at vector math, so there may be an obvious solution to this that I'm missing. Most Internet resources about the SAT just assume that you can always iterate over the vertices of a polygon in clockwise order.
You can just calculate which direction each polygon is ordered, using, for example, the answer to this question, and then multiply your normal by -1 if the two polygons have different orders.
You could also check each polygon passed to your algorithm to see if it is ordered incorrectly, again using the algorithm above, and reverse the vertex order if necessary.
Note that when calculating the vertex order, some algorithms will work for all polygons and some just for convex polygons.
I finally figured it out, but the one answer posted was not the complete solution so I'm not going to accept it. I was able to determine the ordering of the polygon using the basic algorithm described in this SO answer (also described less clearly in David Norman's link), which is:
for each edge in polygon:
sum += (x2 - x1) * (y2 + y1)
However, there's an important caveat which none of these answers mention. Normally, you can decide that the polygon's vertices are clockwise if this sum is positive, and counterclockwise if the sum is negative. But the comparison is inverted in Java's 2D graphics system, and in fact in many graphics systems, because the positive y axis points downward. So in a normal, mathematical coordinate system, you can say
if sum > 0 then polygon is clockwise
but in a graphics coordinate system with an inverted y-axis, it's actually
if sum < 0 then polygon is clockwise
My actual code, using Java's Polygon, looked something like this:
//First, find the normals as if the polygon was clockwise
int sum = 0;
for(int i = 0; i < polygon.npoints; i++) {
int nextI = (i + 1 == polygon.npoints ? 0 : i + 1);
sum += (polygon.xpoints[nextI] - polygon.xpoints[i]) *
(polygon.ypoints[nextI] + polygon.ypoints[i]);
}
if(sum > 0) {
//reverse all the normals (multiply them by -1)
}
I have two points at the end of a line.
I need to get the end coordinates of a translation of this line.
The translation will be a parallel line that is a distance d from the original line.
here is an image of what i need:
So I need a function that I can pass these two points and the distance and get the two new coordinates in returns.
I have been stuck on this problem for a while. Any help will be appreciated!
Thanks you!
The new co-ordinates will be the resulting vector of
distance d multiplied by normalized vector of which direction it's moving, added to the original vector point.
EDIT:
Given the two points of the line, you will need to calculate the normal of the vector joining these points. Information on that is here..
Normalise this vector, multiply by d, add to each point.
Calculate the vector (x2-x1,y2-y1). This is a vector in the direction of your line. A normal vector is then given by
(-(y2-y1),-(x2-x1)) = (y1-y2,x1-x2).
Divide this vector by its size to get the unit vector in the direction you want
A = (y1-y2,x1-x2)/|(y1-y2,x1-x2)|
Now given your distance d your translated point will be given by
NewPoint = OldPoint + d * A