determinant of 3 points in java - java

I am creating a java application. I need to calculate the determinant of three point. I have calculated it:
static int determinant(Point point1, Point point2, Point point3) {
int x1 = point1.x;
int x2 = point2.x;
int x3 = point3.x;
int y1 = point1.y;
int y2 = point2.y;
int y3 = point3.y;
return (x1 * y2) + (x3 * y1) + (x2 * y3) - (x3 * y2) - (x2 * y1)
- (x1 * y3);
}
(I am not good in math)But, I found the following when I searched about it:
public int ccw(int p1, int p2, int p3)
{
return (xPoints[p2] - xPoints[p1])*(yPoints[p3] - yPoints[p1]) - (yPoints[p2] - yPoints[p1])*(xPoints[p3] - xPoints[p1]);
}
which one is the correct method? If the first method is the correct one, what does the second method do?

both equations are the same. there is no mathematical difference between the two.
someone better at math than I could probably give you the mathematic proof. I chose to go the practical route, implemented in python, because I can
def fun1(p1,p2,p3) :
print (p1[0]*p2[1])+(p3[0]*p1[1])+(p2[0]*p3[1]) - (p3[0]*p2[1]) - (p2[0]*
p1[1]) - (p1[0]*p3[1])
def fun2(p1,p2,p3) :
print (p2[0]-p1[0])*(p3[1]-p1[1])-(p2[1] - p1[1])*(p3[0]-p1[0])
>>> fun1((0,0),(9,1),(3,2))
15
>>> fun2((0,0),(9,1),(3,2))
15
>>> fun2((33,5),(4,6),(8,1))
141
>>> fun1((33,5),(4,6),(8,1))
141
for any 3 points, fun1 and fun2 will yield the same result.

The second version assumes that the points are defined in two one-dimensional arrays:
int [] xPoints;
int [] yPoints;
xPoints[p] holds the x position of point p
yPoints[p] holds the y position of point p
I haven't done the math, but perhaps the two methods actually calculate the same thing.

Related

Imagine slicing a polygon like a pizza haphazardly, how would you find the largest slice?

I have a polygon that have been divided up with multiple lines, creating new smaller polygons that make up the whole. How would I go about finding the slice with the largest area?
Imagine something like this: sliced polygon green points are vertices, lines intersect creating more vertices, looking for the largest yellow marked area.
I figured this could be solved by generating a directed graph in order to define each unique shape. I can't come up with a way to link all vertices correctly though.
All vertices and edge lengths are either given or calculated with these methods.
public static double calcDistanceBetweenPoints(Point a, Point b){
return Math.sqrt((b.y - a.y) * (b.y - a.y) + (b.x - a.x) * (b.x - a.x));
}
public static Point findIntersection(Point A, Point B, Point C, Point D){
// Line AB represented as a1x + b1y = c1
double a1 = B.y - A.y;
double b1 = A.x - B.x;
double c1 = a1*(A.x) + b1*(A.y);
// Line CD represented as a2x + b2y = c2
double a2 = D.y - C.y;
double b2 = C.x - D.x;
double c2 = a2*(C.x)+ b2*(C.y);
double determinant = a1*b2 - a2*b1;
if (determinant == 0)
{
// The lines are parallel
return new Point(Double.MAX_VALUE, Double.MAX_VALUE);
}
else
{
double x = (b2*c1 - b1*c2)/determinant;
double y = (a1*c2 - a2*c1)/determinant;
return new Point(x, y);
}
}
Data collected from the System.in input stream looks something like this:
n m
x1 y1
x.. y...
xn yn
x11 y11 x21 y21
x.. y.. x.. y..
x1m y1m x2m y2m
So I get all the starting and ending points for each line from the input.
Thanks for the help

Find points on triangle

I have 3 vertices of a triangle and I'm trying to find all the integer points that lie on the inside and ON THE SIDES of the triangle. I've tried numerous methods and they all succeed in finding the inside points, but fail in finding the points on the sides of the triangle. Currently I'm using barycentric coordinates:
private static boolean pointInTriangle(int[] p, int[] c1, int[] c2, int[] c3){
float alpha = ((c2[1] - c3[1])*(p[0] - c3[0]) + (c3[0] - c2[0])*(p[1] - c3[1])) /
((c2[1] - c3[1])*(c1[0] - c3[0]) + (c3[0] - c2[0])*(c1[1] - c3[1]));
float beta = ((c3[1] - c1[1])*(p[0] - c3[0]) + (c1[0] - c3[0])*(p[1] - c3[1])) /
((c2[1] - c3[1])*(c1[0] - c3[0]) + (c3[0] - c2[0])*(c1[1] - c3[1]));
float gamma = 1.0f - alpha - beta;
return ( (alpha>=0.0f) && (beta>=0.0f) && (gamma>=0.0f) );
For example, for vertices (0,0),(0,10),(10,10) this does find (10,8) but it also finds (11,8) which is not correct.
Can somebody help me?
Thanks in advance!
Use the code you alreay have to find if a position is inside the triangle. Then for the other part, if a point is on the line or not..
I would do it like this..
Check by calculating the distance between 2 vertices at a time.
Lets say we have vertices a, b and c. And the point p.
Check if p is on the line between a and b.
This can be done by measuring the distance between a -> p and p -> b.
If those two distances equals the distance of a -> b then it is on the line. If p should be off the line the distance will be longer.
Here is a method to caluclate distance (pythagoran teorem):
private static double GetDistance(double x1, double y1, double x2, double y2)
{
double a = Math.abs(x1-x2);
double b = Math.abs(y1-y2);
return Math.sqrt(a * a + b * b);
}

Collision Detection Issues

I have a little issue with my Collision Detection System for a Game.
In the game are several structures which connect to each other. However they should not connect when there is another structure in between them.
For some weird reason it sometimes fails to connect to directly adjacent structures when there is a structure in a direct line behind them. Rarely it produces other weird connections.
Picture:
The red marked nodes are supposed to be connected.
Code:
public void drawConnections(Graphics g) {
ArrayList<EnergyContainer> structurecopy = (ArrayList<EnergyContainer>) Mainclass.structures.clone(); //all structures in a list
structurecopy.remove(this); //as we are member of the list
structurecopy.removeIf(t -> (!hasStructureInRangeWithoutObstaclesInBetween(t)));
structurecopy.removeIf(t -> !t.receivesEnergyfromNeighbors()); //unimportant check if it is allowed to connect (its working)
structurecopy.forEach(t -> drawConnectionTo(t, g)); //also works fine
}
public boolean hasStructureInRangeWithoutObstaclesInBetween(Structure structureWhichShouldBeInRange) {
// if in Range
if (getRange() >= Math.hypot(structureWhichShouldBeInRange.getX() - getX(),
structureWhichShouldBeInRange.getY() - getY())){ //checks if structure is in range
ArrayList<EnergyContainer> structureclone = (ArrayList<EnergyContainer>) Mainclass.structures.clone();
structureclone.remove(this); //again removes itself from the list
structureclone.remove(structureWhichShouldBeInRange); //also removes target - so it doesn't block itself
structureclone.removeIf(t -> !t.collidesWithLine(this.getX(), structureWhichShouldBeInRange.getX(),
this.getY(), structureWhichShouldBeInRange.getY())); //removes it when it does not collide
return structureclone.size() == 0; //returns true when no collisions are found
}
return false;
}
public boolean collidesWithLine(int x1, int x2, int y1, int y2) {
// Line Segment - Circle Collision Detection
double dx = x2 - x1;
double dy = y2 - y1;
double a = dx * dx + dy * dy; //this is the distance
double b = 2 * dx * (x1 - getX()) + 2 * dy * (y1 - getY());
double c = getX() * getX() + getY() * getY() + x1 * x1 + y1 * y1 - 2 * (getX() * x1 + getY() * y1)
- getCollisionRadius() * getCollisionRadius();
double discriminant = b * b - 4 * a * c;
return discriminant >= 0; // no intersection -> discriminant <0
}
(I added the comments for this text only, so please ignore them if they'd cause compile errors).
Can someone tell me what I am doing wrong?
There might be a couple problems here:
First: As Marat stated: b may be return a value of 0. This is would be happening if your getX() and getY() are returning x1 and y1. If that's the case, you are essentially doing this: (2dx * 0) + (2dy * 0). If that's the case, it can negatively impact your later equations.
Secondly: More than likely, you are ALWAYS returning true from this courtesy of your final equation:
double discriminant = b * b - 4 * a * c;
//This breaks down to discriminant = b^2 * 4ac
Even if b is 0 at this point, as long as either a or c have a value greater than 0, return discriminant >= 0; will be true;
I would HIGHLY recommend putting a breakpoint in at the 2 parts I mentioned and check your values prior to and after the code executing so you can see what's going on with the math.
Also, the Unity API has collision detection functions. You should look in to that. https://docs.unity3d.com/Manual/PhysicsSection.html
Hope that helps.
Assumption:
1 If I understand correctly, these are methods of some Structure class.
2 hasStructureInRangeWithoutObstaclesInBetween is the only caller of collidesWithLine or at least that's how the question is presented.
Because of (2) b is always 0.
I have a feeling it was not your intention. Please revisit you collidesWithLine method.

To determine if a point lies on a line [duplicate]

This question already has answers here:
Check is a point (x,y) is between two points drawn on a straight line
(11 answers)
Closed 9 years ago.
I am trying to find if a particular point lies on a line. What I have tried is . I find the slope of the line .Then I find the slope of the point with the initial coordinates of the line, say x1 and y1. IF both the slopes are equal then the point lies on the line .But because I am using double or even with float I get values with five decimal places and the slope are never equal. the code is as follows.
line.slope == (yTouch-line.yTouch1)/(xTouch-line.xTouch1)
Hi I am not able to add a comment.Can you please tell me what is an error delta
Assume the coordinates of the point to be tested are (x,y)
If you know the equation (say y=mx+c) then just substitute x and y in and check for equality. eg is (3,1) on y=2x-5 ?
1 = 2(3)-5 = 1 so it is on the line
If you don't know the equation but have two points (x1,y1) and (x2,y2) then first calculate the slope m= (y2-y1)/(x2-x1) and then use the y-y1=m(x-x1) form of the equation of a line and check for equality again.
e.g. is the point (4,4) on the line thru (2,3) and (5,4) ?
m=(4-3)/(5-2)=1/3
the equation is y-3=(1/3)(x-2)
and ....well it isnt
Alternatively, just get a 14 year old in your country to explain it to you. In my experience 14 year olds (think they ) know everything !
Hey go with geometric terms,
If your points are (x1, y1) and (x2, y2), and you want to find the point (x3, y3) that is n units away from point 2:
d = sqrt((x2-x1)^2 + (y2 - y1)^2) #distance
r = n / d #segment ratio
x3 = r * x2 + (1 - r) * x1 #find point that divides the segment
y3 = r * y2 + (1 - r) * y1 #into the ratio (1-r):r
Here's link!
Here is solution
public static void checkForLineInaPoint(Double x1, Double y1, Double x2, Double y2)
{
Double m = getSlope(x1,y1,x2,y2);
Double c = getConstant(x1,y1,x2,y2,m);
Double x3= new Double(10.001);
Double y3= new Double(10.001);
if(checkPointLiesonLine(x3,y3,m,c))
System.out.print("Yes");
else
System.out.print("No");
}
private static boolean checkPointLiesonLine(Double x3, Double y3, Double m, Double c)
{
Double temp = m*x3+c;
return temp.compareTo(y3)==0;
}
private static Double getConstant(Double x1, Double y1, Double x2, Double y2, Double m)
{
return y1-m*x1;
}
private static Double getSlope(Double x1, Double y1, Double x2, Double y2)
{
return (y2-y1)/(x2-x1);
}

Calculating the angle between two lines without having to calculate the slope? (Java)

I have two Lines: L1 and L2. I want to calculate the angle between the two lines. L1 has points: {(x1, y1), (x2, y2)} and L2 has points: {(x3, y3), (x4, y4)}.
How can I calculate the angle formed between these two lines, without having to calculate the slopes? The problem I am currently having is that sometimes I have horizontal lines (lines along the x-axis) and the following formula fails (divide by zero exception):
arctan((m1 - m2) / (1 - (m1 * m2)))
where m1 and m2 are the slopes of line 1 and line 2 respectively. Is there a formula/algorithm that can calculate the angles between the two lines without ever getting divide-by-zero exceptions? Any help would be highly appreciated.
This is my code snippet:
// Calculates the angle formed between two lines
public static double angleBetween2Lines(Line2D line1, Line2D line2)
{
double slope1 = line1.getY1() - line1.getY2() / line1.getX1() - line1.getX2();
double slope2 = line2.getY1() - line2.getY2() / line2.getX1() - line2.getX2();
double angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
return angle;
}
Thanks.
The atan2 function eases the pain of dealing with atan.
It is declared as double atan2(double y, double x) and converts rectangular coordinates (x,y) to the angle theta from the polar coordinates (r,theta)
So I'd rewrite your code as
public static double angleBetween2Lines(Line2D line1, Line2D line2)
{
double angle1 = Math.atan2(line1.getY1() - line1.getY2(),
line1.getX1() - line1.getX2());
double angle2 = Math.atan2(line2.getY1() - line2.getY2(),
line2.getX1() - line2.getX2());
return angle1-angle2;
}
Dot product is probably more useful in this case. Here you can find a geometry package for Java which provides some useful helpers. Below is their calculation for determining the angle between two 3-d points. Hopefully it will get you started:
public static double computeAngle (double[] p0, double[] p1, double[] p2)
{
double[] v0 = Geometry.createVector (p0, p1);
double[] v1 = Geometry.createVector (p0, p2);
double dotProduct = Geometry.computeDotProduct (v0, v1);
double length1 = Geometry.length (v0);
double length2 = Geometry.length (v1);
double denominator = length1 * length2;
double product = denominator != 0.0 ? dotProduct / denominator : 0.0;
double angle = Math.acos (product);
return angle;
}
Good luck!
dx1 = x2-x1;
dy1 = y2-y1;
dx2 = x4-x3;
dy2 = y4-y3;
d = dx1*dx2 + dy1*dy2; // dot product of the 2 vectors
l2 = (dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2) // product of the squared lengths
angle = acos(d/sqrt(l2));
The dot product of 2 vectors is equal to the cosine of the angle time the length of both vectors. This computes the dot product, divides by the length of the vectors and uses the inverse cosine function to recover the angle.
Maybe my approach for Android coordinates system will be useful for someone (used Android PointF class to store points)
/**
* Calculate angle between two lines with two given points
*
* #param A1 First point first line
* #param A2 Second point first line
* #param B1 First point second line
* #param B2 Second point second line
* #return Angle between two lines in degrees
*/
public static float angleBetween2Lines(PointF A1, PointF A2, PointF B1, PointF B2) {
float angle1 = (float) Math.atan2(A2.y - A1.y, A1.x - A2.x);
float angle2 = (float) Math.atan2(B2.y - B1.y, B1.x - B2.x);
float calculatedAngle = (float) Math.toDegrees(angle1 - angle2);
if (calculatedAngle < 0) calculatedAngle += 360;
return calculatedAngle;
}
It return positive value in degrees for any quadrant: 0 <= x < 360
You can checkout my utility class here
The formula for getting the angle is tan a = (slope1-slope2)/(1+slope1*slope2)
You are using:
tan a = (slope1 - slope2) / (1 - slope1 * slope2)
So it should be:
double angle = Math.atan((slope1 - slope2) / (1 + slope1 * slope2));
First, are you sure the brackets are in the right order? I think (could be wrong) it should be this:
double slope1 = (line1.getY1() - line1.getY2()) / (line1.getX1() - line1.getX2());
double slope2 = (line2.getY1() - line2.getY2()) / (line2.getX1() - line2.getX2());
Second, there are two things you could do for the div by zero: you could catch the exception and handle it
double angle;
try
{
angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
catch (DivideByZeroException dbze)
{
//Do something about it!
}
...or you could check that your divisors are never zero before you attempt the operation.
if ((1 - (slope1 * slope2))==0)
{
return /*something meaningful to avoid the div by zero*/
}
else
{
double angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
return angle;
}
Check this Python code:
import math
def angle(x1,y1,x2,y2,x3,y3):
if (x1==x2==x3 or y1==y2==y3):
return 180
else:
dx1 = x2-x1
dy1 = y2-y1
dx2 = x3-x2
dy2 = y3-y2
if x1==x2:
a1=90
else:
m1=dy1/dx1
a1=math.degrees(math.atan(m1))
if x2==x3:
a2=90
else:
m2=dy2/dx2
a2=math.degrees(math.atan(m2))
angle = abs(a2-a1)
return angle
print angle(0,4,0,0,9,-6)
dx1=x2-x1 ; dy1=y2-y1 ; dx2=x4-x3 ;dy2=y4-y3.
Angle(L1,L2)=pi()/2*((1+sign(dx1))* (1-sign(dy1^2))-(1+sign(dx2))*(1-sign(dy2^2)))
+pi()/4*((2+sign(dx1))*sign(dy1)-(2+sign(dx2))*sign(dy2))
+sign(dx1*dy1)*atan((abs(dx1)-abs(dy1))/(abs(dx1)+abs(dy1)))
-sign(dx2*dy2)*atan((abs(dx2)-abs(dy2))/(abs(dx2)+abs(dy2)))

Categories