Find points on triangle - java

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);
}

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

calculating shortest grid distance

Consider a city where the streets are perfectly laid out to form an infinite square grid. In this city finding the shortest path between two given points (an origin and a destination) is much easier than in other more complex cities. As a new Uber developer, you are tasked to create an algorithm that does this calculation.
Given user's departure and destination coordinates, each of them located on some street, find the length of the shortest route between them assuming that cars can only move along the streets. You are guaranteed that at least one of the coordinates is an integer.
I am struggling a little to figure out the logic here. There are many cases and I don't know how to accommodate them all. This is what I have so far
double perfectCity(double[] departure, double[] destination) {
double yDist = Math.abs(destination[1]-departure[1]);
double xDist = Math.abs(departure[1] - departure[0] + departure[1]-destination[0]);
return xDist + yDist;
}
The algorithm is very simple if the inputs are integers, just find the absolute value between the x and y coordinates and then add them together. This is called the Manhattan distance.
int distance = Math.abs(x1 - x2) + Math.abs(y1 - y2);
With doubles, it is almost exactly the same, except for one situation. Here are some possibilities:
Both points have integer coordinates
One point has integer coordinates, and the other point has only one integer coordinate
Both points have only one integer coordinate, but they are on different axes.
Both points have only one integer coordinate, and they are on the same axis.
Possibilities 1-3 all work fine using the same algorithm as for finding distance with integers, except #4 has the possibility of the axis in common being on the same block.
For example, if the inputs were: {x: 0.5, y: 2} and {x: 0.5, y: 3} you would have to travel horizontally, vertically, and then backwards horizontally again in order to reach the destination. This is different from inputs of {x: 0.5, y: 2} and {x: 1.5, y: 3} because there is no need to travel backwards on the same axis.
So you can use the normal algorithm in all cases except for the case of when both of the Xs or Ys have floating-point values and have the same floor-ed value.
Your code should look something like this.
import static java.lang.Math.*;
public static double perfectCity(double x1, double y1, double x2, double y2) {
double xDist = abs(x1 - x2);
double yDist = abs(y1 - y2);
if (floor(x1) != x1 && floor(x2) != x2 && // both Xs are doubles
floor(x1) == floor(x2) && // on the same block
y1 != y2) { // not on the same street
xDist = min(abs(x1 - floor(x1) + x2 - floor(x2)),
abs(x1 - ceil(x1) + x2 - ceil(x2)));
} else if (floor(y1) != y1 && floor(y2) != y2 && // both Ys are doubles
floor(y1) == floor(y2) && // on the same block
x1 != x2) { // not on the same street
yDist = min(abs(y1 - floor(y1) + y2 - floor(y2)),
abs(y1 - ceil(y1) + y2 - ceil(y2)));
}
return xDist + yDist;
}
This can be much further simplified by using a helper function to calculate each axis separately.
public static double perfectCity(double x1, double y1, double x2, double y2) {
return travelOnAxis(x1, x2, y1 == y2) + travelOnAxis(y1, y2, x1 == x2);
}
private static double travelOnAxis(double from, double to, boolean travelIsStraight) {
if (Math.floor(from) == Math.floor(to) && !travelIsStraight) {
double dist = Math.abs((from % 1) + (to % 1));
return Math.min(dist, 2 - dist);
} else {
return Math.abs(from - to);
}
}
I used the trick with 2 - dist here because it's the same as calculating
Math.abs((1 - (from % 1)) + (1 - (to % 1)))
which is the same as
Math.abs(from - Math.ceil(from) + to - Math.ceil(to))
If this is a square grid, you can consider the x and y coordinates separately; the minimum distance is the sum of the minumum distances in the two directions.
In the p-direction (either x or y), you have to move from p1 to p2. From p1, you can either move to floor(p1) or ceil(p1) to get to a road (which may be equal, if p1 is an integer); from there, you can move to either floor(p2) or ceil(p2), the road on which p2 is located; from there, you can move to p2.
So, the minimum distance in the p-direction is
min(abs(p1 - ceil(p1) ) + abs(ceil(p1) - floor(p2)) + abs(floor(p2) - p2), # (1)
abs(p1 - floor(p1)) + abs(floor(p1) - ceil(p2) ) + abs(ceil(p2) - p2), # (2)
abs(p1 - floor(p1)) + abs(floor(p1) - floor(p2)) + abs(floor(p2) - p2), # (3)
abs(p1 - ceil(p1) ) + abs(ceil(p1) - ceil(p2) ) + abs(ceil(p2) - p2)) # (4)
So you can just calculate this independently for the x and y directions, and add.
To illustrate this (abbreviating floor and ceil as f and p respectively):
f(p1) p1 c(p1)
+---O>>>>+>>>>>>>>+
.
.
+>>>O----+
f(p2) p2 c(p2)
--------------------------------> p axis
The shortest route is indicated here with >. The .s are on the shortest route, but since that part of the route is orthogonal to the p direction, it "doesn't count" towards the minimum distance in that direction.
The minimum route shown here, p1 -> c(p1) -> f(p2) -> p2, is Case 1 above.
It should not be hard to visualize swapping p1 and p2, in which case the minimum route is to go from p1 ->f(p1) -> c(p2) -> p2 (Case 2).
The case of pN == f(pN) == c(pN) is not very different; then, the part of the expression abs(pN - f(pN)) or abs(pN - c(pN)) is just zero.
The slightly different case is where f(p1) == f(p2):
f(p1) p1 c(p1) f(p1) p1 c(p1)
+---O>>>>+ +<<<O----+
. .
. .
+-----O<<+ +>>>>>O--+
f(p2) p2 c(p2) f(p2) p2 c(p2)
--------------------------------> p axis
In this case, the minimum route can either be p1 -> f(p1) -> f(p2) -> p2 or p1 -> c(p1) -> c(p2) -> p2 (which are Cases 3 and 4, respectively).
As mentioned by 4castle, the problem is trivial if only integers are considered for input. You would never have to "move back" after having "moved forward" in that case since you would always reach your destinaton in a single move.
But since, at most one floating point number needs to be considered for each of departure/destination, we need to consider 3 cases, (warning: lengthy explanation). Below is a python2 implementation with explanations.
x co-ordinates of both departure and destination are the same and are not floating point numbers. In this case, the shortest distance is simply the absolute difference between y co-ordinates. The same logic applies vice-versa.
import math
class Location():
def __init__(self, cord):
self.x = cord[0]
self.y = cord[1]
def perfectCity(departure, destination):
l1 = Location(departure)
l2 = Location(destination)
if l1.x == l2.x and float(l1.x).is_integer() and float(l2.x).is_integer():
return abs(l1.y-l2.y)
if l1.y == l2.y and float(l1.y).is_integer() and float(l2.y).is_integer():
return abs(l1.x-l2.x)
When one of the co-ordinates in the departure is a floating point, then:
If x co-ordinate is floating point, we can move backwards(round down) or move front(round up).
If y co-ordinate is floating point, we can either move down (round down) or move up (round up).
The above logic should work even when there is no floating point co-ordinate since we move in either direction by zero units.
Once we calculate these, we just choose the minimum among those like below,
return min(calc_round_up_dist(l1, l2), cal_round_down_dist(l1, l2))
Lets take an example of (0.4, 1) and (0.9, 3) for below calculations.
While calculating the round_up we need to calculate 3 distances:
round_up_distance: difference between the rounded up value of the floating point co-ordinate and the original floating point co-ordinate. We return zero if there is no floating point co-ordinate. 1 - 0.4 = 0.6 in the above example
non_floating_point difference: difference between the non floating point co-ordinate of departure and the corresponding co-ordinate of destination ( note that this might be floating point or not a floating point abs(3-1) = 2 in the above example
Difference between departure's floating point counterpart in the destination co-ordinate 0.9 in the above case and the new value of departure's floating point after rounding up, 0.4 + 0.6(this is the round_up distance) = 1.0, i.e. abs(0.9 - 1.0) = 0.1
Adding all the 3 above we get 0.6 + 2 + .1 = 2.7 which is the shortest distance.
Corresponding calculation needs to be done for rounding down. And we pick the minimum among both. The code for round_up and round_down is as below,
import math
class Location():
def __init__(self, cord):
self.x = cord[0]
self.y = cord[1]
def floating_point_round_up(self):
if not float(self.x).is_integer():
return math.ceil(self.x) - self.x
if not float(self.y).is_integer():
return math.ceil(self.y) - self.y
return 0
def floating_point_round_down(self):
if not float(self.x).is_integer():
return self.x - math.floor(self.x)
if not float(self.y).is_integer():
return self.y - math.floor(self.y)
return 0
def non_floating_point_diff(self, obj):
if not float(self.x).is_integer():
return abs(self.y - obj.y)
if not float(self.y).is_integer():
return abs(self.x - obj.x)
return abs(self.y - obj.y)
def floating_point_counterpart(self, obj):
if not float(self.x).is_integer():
return obj.x
if not float(self.y).is_integer():
return obj.y
return obj.x
def floating_point(self):
if not float(self.x).is_integer():
return self.x
if not float(self.y).is_integer():
return self.y
return self.x
Round up and down functions are as below,
def calc_round_up_dist(l1, l2):
dist = l1.floating_point_round_up()
diff = l1.non_floating_point_diff(l2)
floating_point_counterpart = l1.floating_point_counterpart(l2)
new_val = dist + l1.floating_point()
return dist + diff + abs(new_val - floating_point_counterpart)
def cal_round_down_dist(l1, l2):
dist = l1.floating_point_round_down()
diff = l1.non_floating_point_diff(l2)
floating_point_counterpart = l1.floating_point_counterpart(l2)
new_val = l1.floating_point() - dist
return dist + diff + abs(floating_point_counterpart - new_val)
Finally the main function that calls the above methods,
def perfectCity(departure, destination):
l1 = Location(departure)
l2 = Location(destination)
if l1.x == l2.x and float(l1.x).is_integer() and float(l2.x).is_integer():
return abs(l1.y-l2.y)
if l1.y == l2.y and float(l1.y).is_integer() and float(l2.y).is_integer():
return abs(l1.x-l2.x)
return min(calc_round_up_dist(l1, l2), cal_round_down_dist(l1, l2))
This is a practice question on CodeSignal:
https://app.codesignal.com/company-challenges/uber/gsjPcfsuNavxhsQQ7
def solution(departure, destination):
# go to the closest integer
# I can only travel the path of an integer
# if the number is a float I need to travel to an integer first
# then travel to the destination
x1, y1 = departure
x2, y2 = destination
res = 0
# check if the coordinations are integers
a = list(map(isInteger, departure))
b = list(map(isInteger, destination))
# if all are integers or if the corresponding elements are different
if a[0] ^ b[0] or (a[0] and a[1] and b[0] and b[1]):
return abs(x1-x2) + abs(y1-y2)
if a[0]:
res += abs(x2-x1)
# cloest distance from y1 to y2
res += getClosest(y1, y2)
else:
res += abs(y2-y1)
# closes distance from x1 to x2
res += getClosest(x1, x2)
return res
def getClosest(y1, y2):
cand1 = math.floor(y1)
cand2 = math.ceil(y1)
# find the integer closer to y1 to move to
res1 = abs(y1-cand1) + abs(cand1-y2)
res2 = abs(y1-cand2) + abs(cand2-y2)
return min(res1, res2)
def isInteger(n):
return n == round(n)

Extrapolate a line beyond two known points

I really suck at math. No, better explanation: I don't know how to interpret mathematical notation. My brain just cant interpret it. That's why I come to the programming community for help "translating" math into a language I do understand.
I have two sets of coordinates in 3d space representing the line of sight.
Vector1(eyes) x=10 y=10 z=4
Vector2(lookingat) x=10 y=8 z=4.785
How do I calculate a point with these double values beyond the looking at value? for example, what lies 2 points beyond the line we are looking it? what location in space would that be?
In short:
How do I extrapolate a given point beyond the line made up by two vectors with given double value along the line.
a known
\
\
\
b known
?
? + 3
?
c what is this value...
Edit
With the help of the answer of #Thrustmaster I came up with this wonderfull solution. Thanks a lot :D
private Vec3 calculateLine(Vec3 x1, Vec3 x2, double distance) {
double length = Math.sqrt(multiply(x2.xCoord - x1.xCoord) + multiply((x2.yCoord - x1.yCoord)) + multiply((x2.zCoord - x1.zCoord)));
double unitSlopeX = (x2.xCoord-x1.xCoord) / length;
double unitSlopeY = (x2.yCoord-x1.yCoord) / length;
double unitSlopeZ = (x2.zCoord-x1.zCoord) / length;
double x = x1.xCoord + unitSlopeX * distance;
double y = x1.yCoord + unitSlopeY * distance;
double z = x1.zCoord + unitSlopeZ * distance;
return Vec3.createVectorHelper(x, y, x);
}
private double multiply(double one) {
return one * one;
}
You need to start looking to basic 3D coordinate geometry.
In 3D, the equation can be written as:
x = x1 + unitSlopeX * distance
y = y1 + unitSlopeY * distance
z = z1 + unitSlopeZ * distance
.. where (x1,y1,z1) can be any point on the line; in this case (10,10,4).
Next set of unknowns is all 3 unitSlopes. To calculate it, simply subtract the two points (this will ive you a vector), and divide by the length of the vector.
length = sqrt((x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2)
unitSlopeX = (x2-x1) / length
unitSlopeY = (y2-y1) / length
unitSlopeZ = (z2-z1) / length
Now, to finally, get your third coordinate, simply plug in distance (any value) into the three equations at the beginning of this post.
In vector notation:
V = V1 + t * (V2 - V1) / | V2 - V1 |
.. where t is any real number.

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);
}

determinant of 3 points in 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.

Categories