Java code to find distance between line and point in 3D space - java

I have a point (x1, y1, z1) in a 3D dimensional space
And a line (x2,y2,z2)(x3,y3,z3)
I want to find the shortest distance between the line and the dot.
I already found mathematical equations for this, but I am not a mathematician, and i failed to understand the different variables in the equation and apply them to Java/Android.
I have searched and viewed the similar questions here and almost everywhere, but there were no example in any programming language.

After spending the night learning some spacial math, I could finally convert the equations to Java code:
public static float betweenPointAndLine(float[] point, float[] lineStart, float[] lineEnd){
float[] PointThing = new float[3];
float[] TotalThing = new float[3];
PointThing[0] = lineStart[0] - point[0];
PointThing[1] = lineStart[1] - point[1];
PointThing[2] = lineStart[2] - point[2];
TotalThing[0] = (PointThing[1]*lineEnd[2] - PointThing[2]*lineEnd[1]);
TotalThing[1] = -(PointThing[0]*lineEnd[2] - PointThing[2]*lineEnd[0]);
TotalThing[2] = (PointThing[0]*lineEnd[1] - PointThing[1]*lineEnd[0]);
float distance = (float) (Math.sqrt(TotalThing[0]*TotalThing[0] + TotalThing[1]*TotalThing[1] + TotalThing[2]*TotalThing[2]) /
Math.sqrt(lineEnd[0] * lineEnd[0] + lineEnd[1] * lineEnd[1] + lineEnd[2] * lineEnd[2] ));
return distance;
}

public static double distance(double x1, double y1, double z1,
double x2, double y2, double z2,
double x3, double y3, double z3) {
double b = Math.sqrt(Math.pow((x2 - x3), 2)
+ Math.pow((y2 - y3), 2)
+ Math.pow((z2 - z3), 2));
double S = Math.sqrt(Math.pow((y2 - y1) * (z3 - z1) - (z2 - z1) * (y3 - y1), 2) +
Math.pow((z2 - z1) * (x3 - x1) - (x2 - x1) * (z3 - z1), 2) +
Math.pow((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1), 2)) / 2;
return 2 * S / b;
}

Related

How to generate a random polygon centered in Java?

I want to generate some randoms polygon but I want it to be more or less centered in the middle of the given window coordinates.
Here is my code, it generates a random polygon but most of the time it's on the bottom of the window and I'd like to have it a bit more centered:
private static final double CORNER_MARGIN = 100.0; // max offset for a corner of the field, to randomize the polygon
private static double[] standardPolygon(double x1, double x2, double y1, double y2) {
// minX maxX minY maxY --> it's the coordinate of the window
double centerX = (x1 + x2) / 2;
double centerY = (y1 + y2) / 2;
// this is a standard polygon "centered" in the middle of the program window
return new double[]{
x1 - (x2 - x1) * RANDOM.nextDouble(), y2 + (y2 - y1) *RANDOM.nextDouble() * CORNER_MARGIN,
x2 + (x2 - x1) * RANDOM.nextDouble(), y2 + (y2 - y1) *RANDOM.nextDouble() * CORNER_MARGIN,
x2 + (x2 - x1) * RANDOM.nextDouble(), y1 - (y2 - y1) *RANDOM.nextDouble() * CORNER_MARGIN,
x1 - (x2 - x1) * RANDOM.nextDouble(), y1 - (y2 - y1) *RANDOM.nextDouble() * CORNER_MARGIN,
};
/*return new double[]{
x1 - RANDOM.nextDouble() * CORNER_MARGIN, y2 + RANDOM.nextDouble() * CORNER_MARGIN, // up left
x2 + RANDOM.nextDouble() * CORNER_MARGIN, y2 + RANDOM.nextDouble() * CORNER_MARGIN, // up right
x2 + RANDOM.nextDouble() * CORNER_MARGIN, y1 - RANDOM.nextDouble() * CORNER_MARGIN, // down right
x1 - RANDOM.nextDouble() * CORNER_MARGIN, y1 - RANDOM.nextDouble() * CORNER_MARGIN, // down left
};*/
}
The code in comment is working but now I tried to center it but I only get some rectangles/squares. How can I manage to keep random polygon forms but a bit more centered ?
[EDIT]
Here is how I draw the area of the polygon :
private void drawZone(Group group, IGameParameters gameParameters) {
Polygon polygon = new Polygon();
double[] points = gameParameters.dronePadDeliveryZonePolygon();
List<Double> pointsList = new ArrayList<>();
for (double point : points) pointsList.add(point);
polygon.getPoints().addAll(pointsList);
polygon.setFill(Color.ANTIQUEWHITE);
group.getChildren().add(polygon);
}```
You calculated the center but don't use it anywhere. Just so I understand correctly, this is a 4-sided polygon only and the corners randomly positioned at most 100 from the corner of the window?
I'm not 100% sure on how you want the polygon to be shaped but give this a try. Logically it works in my head, but I don't have a way to test the code right now.
private static final double CORNER_MARGIN = 100.0;
private static double[] standardPolygon(double x1, double x2, double y1, double y2) {
double centerX = (x1 + x2) / 2;
double centerY = (y1 + y2) / 2;
// Get the corner offsets
ox1 = x1 + CORNER_MARGIN * RANDOM.nextDouble(); // top left
oy1 = y1 + CORNER_MARGIN * RANDOM.nextDouble();
ox2 = x2 - CORNER_MARGIN * RANDOM.nextDouble(); // top right
oy2 = y1 + CORNER_MARGIN * RANDOM.nextDouble();
ox3 = x1 + CORNER_MARGIN * RANDOM.nextDouble(); // bottom left
oy3 = y2 - CORNER_MARGIN * RANDOM.nextDouble();
ox4 = x2 - CORNER_MARGIN * RANDOM.nextDouble(); // bottom right
oy4 = y2 - CORNER_MARGIN * RANDOM.nextDouble();
// Calculate the center of the polygon
double cx = (ox2 - ox1) / 2;
double cy = (oy2 - oy1) / 2;
// difference between window's center and polygon
double offsetX = centerX - cx;
double offsetY = centerY - cy;
// offset the calculated points so the polygon's center matches the window
ox1 += offsetX;
oy1 += offsetY;
ox2 += offsetX;
oy2 += offsetY;
ox3 += offsetX;
oy3 += offsetY;
ox4 += offsetX;
oy4 += offsetY;
// this is a standard polygon "centered" in the middle of the program window
return new double[]{
ox1, oy1,
ox2, oy2,
ox3, oy3,
ox4, oy4
};
}

Find the normal of the intersection between a polygon and a line libgdx

I have modified some code in the Intersector class in libgdx to find the intersection between a line and a polygon. However, I am unsure how to calculate the normal of the point of collision. Below is some code that I have.
public static Vector2 intersectSegmentPolygon (Vector2 p1, Vector2 p2, Polygon polygon) {
float[] vertices = polygon.getTransformedVertices();
float x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y;
int n = vertices.length;
float x3 = vertices[n - 2], y3 = vertices[n - 1];
for (int i = 0; i < n; i += 2) {
float x4 = vertices[i], y4 = vertices[i + 1];
float d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
if (d != 0) {
float yd = y1 - y3;
float xd = x1 - x3;
float ua = ((x4 - x3) * yd - (y4 - y3) * xd) / d;
if (ua >= 0 && ua <= 1) {
float ub = ((x2 - x1) * yd - (y2 - y1) * xd) / d;
if (ub >= 0 && ub <= 1) {
return new Vector2(x1 + (x2 - x1) * ua, y1 + (y2 - y1) * ua);
}
}
}
x3 = x4;
y3 = y4;
}
return null;
}

Finding whether a point is within a triangle

I have been on this for hours, attempting different methods looking at just about every question. Perhaps I have it completely wrong, but I feel that I have my math of it correct, but no matter what numbers I input, I get the same output. My code is off somewhere and I have to turn it in by midnight.
It is the all so fun: Find if a point is within a triangle code. (for beginners)
import java.util.Scanner;
public class PointsTriangle {
// checks if point entered is within the triangle
//given points of triangle are (0,0) (0,100) (200,0)
public static void main (String [] args) {
//obtain point (x,y) from user
System.out.print("Enter a point's x- and y-coordinates: ");
Scanner input = new Scanner(System.in);
double x = input.nextDouble();
double y = input.nextDouble();
//find area of triangle with given points
double ABC = ((0*(100-0 )+0*(0 -0)+200*(0-100))/2.0);
double PAB = ((x*(0 -100)+0*(100-y)+0 *(y- 0))/2.0);
double PBC = ((x*(100-0 )+0*(0 -y)+200*(y-100))/2.0);
double PAC = ((x*(0 -100)+0*(100-y)+200*(y- 0))/2.0);
boolean isInTriangle = PAB + PBC + PAC == ABC;
if (isInTriangle)
System.out.println("The point is in the triangle");
else
System.out.println("The point is not in the triangle");
}//end main
}//end PointsTriangle
You placed the wrong value order into your formula; therefore, the result is wrong. If the 3 vertices are as the following
A(x1, y1) B(x2, y2), C(x3, y3)
then the area is calculated as
double ABC = Math.abs (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2;
After that, you just replace each vertex with the input point, we will have the following triangles: PBC, APC, ABP.
Put everything together, we will have the correct one
int x1 = 0, y1 = 0;
int x2 = 0, y2 = 100;
int x3 = 200, y3 = 0;
// no need to divide by 2.0 here, since it is not necessary in the equation
double ABC = Math.abs (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2));
double ABP = Math.abs (x1 * (y2 - y) + x2 * (y - y1) + x * (y1 - y2));
double APC = Math.abs (x1 * (y - y3) + x * (y3 - y1) + x3 * (y1 - y));
double PBC = Math.abs (x * (y2 - y3) + x2 * (y3 - y) + x3 * (y - y2));
boolean isInTriangle = ABP + APC + PBC == ABC;
If you draw a picture, you can see the point has to satisfy simple inequalities (below / above / to the right of certain lines). Whether "on the edge" is in or out I will leave up to you:
Y > 0 (above the X axis)
X > 0 (to the right of the Y axis)
X + 2* Y < 200 (below the hypotenuse)
Write an if statement around these three and you're done:
if( (y > 0) && (x > 0) && (x + 2*y < 200) )
System.out.println("The point is in the triangle");
else
System.out.println("The point is not in the triangle");

Java - Collision Detection of Two Lines

I have a game where enemies are made of lines with a large g2d.setStroke(); How would I find collision between this line and another line?
Here is where I draw it:
g2d.setStroke(new BasicStroke(thickness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
//thickness = 35 --- declared previously
g2d.drawLine(x1, y1, x2, y2);
As math does not seem to be your favourite topic, so let's keep it simple and
use school math.
g2d.drawLine(x1, y1, x2, y2);
g2d.drawLine(u1, v1, u2, v2);
A point on the the two line pieces would be:
(x, y) = (x1, y1) + alpha * (x2 - x1, y2 - y1) where alpha in (0 .. 1).
(x, y) = (u1, v1) + beta * (u2 - u1, v2 - v1) where beta in (0 .. 1).
Any intersecting point has to be on those two line pieces, hence:
x1 + alpha * (x2 - x1) = u1 + beta * (u2 - u1);
y1 + alpha * (y2 - y1) = v1 + beta * (v2 - v1);
which is the same as:
alpha * (x2 - x1) = (u1 - x1) + beta * (u2 - u1);
alpha * (y2 - y1) = (v1 - y1) + beta * (v2 - v1);
If there is a solution for alpha and beta within { 0, ..., 1 }, you have got it.
If any cofactor - like (x2 - x1) - is 0, you have a simple solution.
Otherwise you can divide/multiply by a cofactor.
Or you could invest a bit of time learning linear algebra basics, matrices and determinants and such. With that knowledge one can also determine whether a 3D surface is turned toward you, or not: the normal vector.

Why is this line intersection code not working?

I have the following code to determine the intersection of two 2D lines. It's not working and I'm not sure why; I've been copying code from multiple sources without much change.
The lines extend infinitely from a given midpoint. The "vector()" referenced in the below code is a 2D vector of magnitude 1.0 that indicates the direction in which the line extends (the line also extends in the negative direction, it's not a ray).
Earlier, I was using this method for determining the intersection: Intersection point of two lines (2 dimensions)
After that gave me wrong results, I went with the method on Wikipedia.
float x1 = line1.location().x();
float y1 = line1.location().y();
float x2 = x1 + line1.vector().x();
float y2 = y1 + line1.vector().y();
float x3 = line2.location().x();
float y3 = line2.location().y();
float x4 = x3 + line2.vector().x();
float y4 = y3 + line2.vector().y();
float d = ((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4));
if(d == 0) // If parallel, defaults to the average location of the lines.
return new Vector2f((x1 + x3) * 0.5f, (y1 + y3) * 0.5f);
else
{
float a = (x1 * y2) - (y1 * x2);
float b = (x3 * y4) - (y3 * x4);
return new Vector2f(((a * (x3 - x4)) - ((x1 - x2) * b)) / d,
((a * (y3 - y4)) - ((y1 - y2) * b)) / d);
}
Two examples of how it is wrong (The orange dot is the returned point of intersection):q
It returns a point along the primary line, but it doesn't return a point on the second. the same bugs happen in both methods, so I'm really not sure what I'm doing wrong.
How can I fix this?
EDIT: Actually, this code works fine; my visualization code had an error.
I believe you've confused what the location() and vector() methods return. Unless i'm mistaken the location().x() gives you a point on the line created by the vector while vector().x() gives you the magnitude of the x value of the vector. (e.g. a horizontal has a vector().y() of 0)
You are adding the magnitude of the vector to the starting point. Instead try multiplying the starting point by the magnitude
float x2 = x1 * line1.vector().x();
float y2 = y1 * line1.vector().y();
As it turns out, the code was working; my visualization code had a bug in it. My bad.

Categories

Resources