Tetrahedron orientation for triangle meshes - algorithm

I have 2 triangles and vertices p0, p1, p2, p3. These two triangle share an edge. From these two triangle I want to make a tetrahedron given by the 4 vertices. The library which I work with requires that "the 4 vertices should be given such that the four vertex triples defining the tetrahedron faces in the drawing appear in counter-clockwise order when being viewed at from the outside" . Assuming one of the two triangles is p0, p1, p2 I calculate the normal as being (p1-p0) (cross) (p2-p0). Can someone please tell me a way to ensure that this condition is met ?

Short answer:
The condition is that p3 must be on the correct side of the plane determined by (p0, p1, p2).
So, after computing the normal for this plane, you need to determine if the vector from (say) p0 to p3 is pointing in the same direction of the normal, or the opposite direction, by taking the dot product dot(normal, p3-p0).
More mathematically speaking:
You need to find the determinant of the 4x4 matrix formed by the homogeneous coordinates of the four points. The sign of the determinant determines if the condition is met; the appropriate sign depends on the exact conventions used, but ideally it should be positive:
require:
0 < det(p0, p1, p2, p3)
== det [ p0.x p0.y p0.z 1 ]
[ p1.x p1.y p1.z 1 ]
[ p2.x p2.y p2.z 1 ]
[ p3.x p3.y p3.z 1 ]
If a particular ordered set of points has a negative determinant, you can fix it by swapping any two of the points (which will negate the determinant):
e.g., swapping p0 and p2:
det(p0, p1, p2, p3) = - det(p2, p1, p0, p3)
^ ^ ^ ^
or, more generally, switching between even and odd permutations of the four vertices.
If the determinant is zero, the four points are co-planar, and cannot be fixed like this.
Finally, the code:
A relatively simple way to compute this determinant with 3-d vector math:
let: v1 = p1 - p0
v2 = p2 - p0
v3 = p3 - p0
norm12 = cross(v1, v2)
-> determinant = dot(norm12, v3)
The final determinant is also known as the "triple product" of v1, v2, and v3.
Note that I have hesitated to try to decode the exact sign convention (i.e., whether you need the determinant to be positive or negative) from your question: the wording and diagram you supply is more than a bit confusing.
Since you have the original library and its documentation, though, you are in the best position to answer this question. As a last resort, you can try the empirical method: try both signs, and pick the one that doesn't blow up...

Related

What algorithm can be used to detect gaps between polygons?

What algorithms are used to find gaps between adjacent polygons (example pictures show 2 adjacent polygons and a shaded 'gap' between them), and is there a common name for this type of operation? Polygons in my input may have coincident vertices, segments, both, or neither. Polygons are represented as ordered lists of points. Adjacent polygons are defined as having at least one coincident point or segment.
I am developing in Go (and have access to the GEOS library), but any references to algorithm steps or implementations in common languages would be helpful.
This might not be what you were looking for, but something like this might get the job done.
Suppose you can calculate a list of all points of intersection p1, p2, …, pk between the perimeters of the two polygons. Let v1, v2, …, vn be the vertices of the first polygon, and w1, w2, …, wm be the vertices of the second polygon.
First, create two ordered collections c1 and c2, where c1 contains p1, p2, …, pk and v1, v2, …, vn, in order (so that if going around the perimeter of the polygon in the clockwise direction, the vertices appear in the list in the order visited), and c2 contains p1, p2, … pk and w1, v2, …, vm ordered in the same way.
Now, between every two adjacent p(i%k) and p((i+1)%k) there is some overlap or gap. This overlap or gap may be degenerate iff the vertices appearing in c1 and c2 between these two points of intersection are the same; in this case, the polygon traced out has area zero and may be discarded. Otherwise, we must see whether the vertices in c1 and c2 appearing between the points of intersection define a gap or an overlap.
If we have an easy/cheap way of testing whether a point is contained within the original polygon, simply choose a point in the space (e.g., the center of the triangle formed by one of the points of intersection and each of the adjacent points in c1 and c2 is guaranteed to be inside the space) and see whether the point is included in either c1 or c2 (it cannot be in one and not the other; why?). If the point is included, then you have an overlap; otherwise, you have a gap.
Indeed, we do have an easy way. If we are going around the first polygon in clockwise order, then if the point identified above (the middle of the triangle so described) is to the right of the line segment formed by the point of intersection and the vertex in c1 adjacent to it, then it's an overlap; otherwise, it's a gap. Alternatively, you can go clockwise around the points in c2 and use the same rule to tell.
To see whether a point is to the left or right of a vector:
take the vector (e.g., the point of intersection to the adjacent point in either c1 or c2)
take the vector to the candidate point (e.g., the center of the triangle described earlier)
Compute the 3-dimensional cross product
The sign of the z-coordinate of the resulting vector gives the answer.
In this example:
p1, p2, p3 ~ (3.1, 5.5), (3.3, 4), (3.8, 2)
v1, v2, v3, v4, v5 ~ (1, 0), (1, 8), (4, 4.5), (2, 3), (3.8, 2)
w1, w2, w3, w4 ~ (4, 1), (3, 5), (4, 9), (9, 5)
c1 ~ (v1, v2, p1, v3, p2, v4, p3=v5)
c2 ~ (w1, p3, p2, w2, p1, w3, w4)
pairs of points of intersection adjacent in c1:
x1 = (p1, p2), x2 = (p2, p3), x3 = (p3, p1)
pairs of points of intersection adjacent in c2:
y1 = (p3, p2), y2 = (p2, p1), y3 = (p1, p3)
triangle for x1 has vertices (p1, v3, w2), middle is
~ ((3.1+4+3)/3, (5.5+4.5+5)/3) = (3.3, 5)
vector from p1 to v3 ~ (0.9, -1)
vector from p1 to middle of triangle ~ (0.2, -0.5)
cross product of p1-v3 x middle of triangle vector:
+0.9 -1.0 +0.0
+0.2 -0.5 +0.0
i j k
=> -0.45k
this has a negative sign, so this is an overlap
triangle for x2 has vertices (p2, v4, p3=v5), middle is
~ ((3.3+2+3.8)/3, (4+3+2)/3) = (3, 3)
vector from p2 to v4: (-1.3, -1)
vector from p2 to middle of triangle: (-0.3, -1)
cross product of p2-v4 and middle of triangle vector:
-1.3 -1.0 +0.0
-0.3 -1.0 +0.0
i j k
=> 1.3k
this has a positive sign, so this must be a gap

Algorithm to determine if two points moving around circle are approaching or separating

I'm looking for an algorithm to determine if the distance between 2 points (p1, p2), moving around a circle at know velocity is increasing or decreasing from the perspective of the smaller arc between them.
I know the position of p1 & p2 in degrees/radians.
I know the speed (piV, p2V) of both objects on a uniform scale.
I know the absolute value of the short arc between p1 & p2 in degrees/radians (always a positive value). But, if it helps I can also know the short arc as a negative or positive value in the sense that it is negative from the perspective of p1 when p2 is behind (right) and positive if p2 is in front (left).
Speed is positive when they are moving counter clockwise and negative if they are "retrograde" (moving clockwise).
The real challenge of this question lies in dealing with the polar coordinate singularity at 180 degrees, so I will skip this and use vector math instead, which is slightly less efficient but much easier to understand. Hopefully someone else more adept with modular arithmetic can resolve this issue.
Converting the angular position to Cartesian:
(X, Y) = R * (cos θ, sin θ)
Assume the objects have Cartesian coordinates P1, P2. Introduce the 2D cross-product:
A ^ B = Ax By - Ay Bx
This is positive if A is clockwise rotated with respect to Be, and vice versa.
Assume the objects have angular velocities W1, W2, where a positive sign means travelling anti-clockwise as is conventional for polar coordinates.
When object 2 is clockwise rotated w.r.t. object 1 (P1 ^ P2 < 0, as in your diagram):
If W1, W2 > 0 and W2 > W1
or, if W1, W2 < 0 and -W1 > -W2
or if W1 < 0 and W2 > 0
... the objects are travelling towards each other; and vice versa for the opposite situation, swapping object labels. Compiling this into a single condition:
sign(W1 - W2) == sign(P1 ^ P2) != 0
Btw, P1 ^ P2 = R^2 sin(θ2 - θ1) using a trig identity, so simply checking the sign of sin(θ2 - θ1) would work.
Edit: turns out reducing the condition down to a single sine term makes the modular logic much clearer, by considering the behaviour of the sine function -
sign(P1 ^ P2) = sign(180 - [θ2 - θ1] % 360)
Thanks to #beta for his comment and which prodded me in the right direction. I had missed the fact that I could use the direction (positive or negative) that p1 is from p2 and which was already known. There was therefore no need to convert the values into other coordinate systems.
The answer is quite simple:
SIGN((p2V - p1V) * Angle) = (+ if separating, - when closing or approaching)
I reduced this to the following C code:
return ((p2V - p1V) * angle) > 0 ? 1 : -1;
This works well if one is using a signed separating Angle that is positive if p2 is counter clockwise (left) from p1 and negative when p2 is clockwise (right) from p1.
Move the reference system to p1. Now you have a static point p1 and p2 moving with velocity of p2V - p1V starting from position p2-p1. Now the question is: when will p2 hit the origin?
Unfortunately, there are three cases here, depending on sign of p2V - p1V:
The speed is zero, points will never collide.
The speed is positive, meaning that p2 will go round the circle and hit 360 degrees.
The speed is negative, meaning that p2 will go straight to the origin and hit 0 degrees.
The only other gotcha is to calculate initial position of p2 - p1 correctly. I'd recommend assuming that initial positions are between 0 and 359, and then adjusting p2 - p1 correspondingly (if it's negative, add 360). Basically, calculating everything "modulo 360".

Getting a list of locations within a triangle in the form of x,y positions

Let's say I have a triangle given by the three integer vertices (x1,y1), (x2,y2) and (x3,y3). What sort of algorithm can I use to return a comprehensive list of ALL (x,y) integer pairs that lie inside the triangle.
The proper name for this problem is triangle rasterization.
It's a well researched problem and there's variety of methods to do it. The two popular methods are:
Scan line by scan line.
For each scan-line you require some basic geometry to recalculate
the start and the end of the line. See Bresenham's Line drawing algorithm.
Test every pixel in the bounding box to see if it is in the
triangle.
This is usually done by using barycentric co-ordinates.
Most people assume method 1) is more efficient as you don't waste time testing pixels that can are outside the triangle, approximately half of all the pixels in the bounding box. However, 2) has a major advantage - it can be run in parallel far more easily and so for hardware is usually the much faster option. 2) is also simpler to code.
The original paper for describing exactly how to use method 2) is written by Juan Pineda in 1988 and is called "A Parallel Algorithm for Polygon Rasterization".
For triangles, it's conceptually very simple (if you learn barycentric co-ordindates). If you convert each pixel into triangle barycentric coordinates, alpha, beta and gamma - then the simple test is that alpha, beta and gamma must be between 0 and 1.
The following algorithm should be appropriate:
Sort the triangle vertices by x coordinate in increasing order. Now we have two segments (1-2 and 2-3) on the one side (top or bottom), and one segment from the other one (1-3).
Compute coefficients of equations of lines (which contain the segments):
A * x + B * y + C = 0
A = y2 - y1
B = x1 - x2
C = x2 * y1 - x1 * y2
There (x1, y1) and (x2, y2) are two points of the line.
For each of ranges [x1, x2), (x2, x3], and x2 (special case) iterate over integer points in ranges and do the following for every x:
Find top bound as y_top = (- A1 * x - C1) div B1.
Find bottom bound as y_bottom = (- A2 * y - C2 - 1) div B2 + 1.
Add all points between (x, y_bottom) and (x, y_top) to the result.
This algorithm is for not strictly internal vertices. For strictly internal vertices items 3.1 and 3.2 slightly differ.
I suppose you have a list of pairs you want to test (if this is not what your problem is about, please specify your question clearly). You should store the pairs into quad-tree or kd-tree structure first, in order to have a set of candidates which is small enough. If you have few points, this is probably not worth the hassle (but it won't scale well if you don't do it).
You can also narrow down candidates further by testing against a bounding box for your triangle.
Then, for each candidate pair (x, y), solve in a, b, c the system
a + b + c = 1
a x1 + b x2 + c x3 = x
a y2 + b y2 + c y3 = y
(I let you work this out), and the point is inside the triangle if a b and c are all positive.
I like ray casting, nicely described in this Wikipedia article. Used it in my project for the same purpose. That method scales on other polygons too, including concave. Not sure about the performance, but it is easily coded, so you could try it yourself (I had no performance issues in my project)

Diagonal of polygon is inside or outside?

I have three consecutive points of polygon, say p1,p2,p3. Now I wanted to know whether the orthogonal between p1 and p3 is inside the polygon or outside the polygon.
I am doing it by taking three vectors v1,v2 and v3. And the point before the point p1 in polygon say p0.
v1 = (p0 - p1)
v2 = (p2 - p1)
v3 = (p3 - p1)
With reference to this question, I am using the method shown in the accepted answer of that question. It is only for counterclockwise. What if my points are clockwise.
I am also knowing my whole polygon is clockwise or counterclockwise. And accordingly I select the vectors v1 and v2. But still I am getting some problem. I am showing one case where I am getting problem.
This polygon is counterclockwise. and It is starting from the origin of v1 and v2.
Since your points are cnosecutive, you can solve this problem by checking the orientation of the triangle p1 p2 p3. If the orientation is the same as the one of the polygon, then the diagonal is in the inside, else on the outside.
To determine the orientation of the triangle, the simplest way is to compute the signed area and check the sign. Compute
p1.x * p2.y + p2.x * p3.y + p3.x * p1.y - p2.x * p1.y - p3.x * p2.y - p1.x * p3.y
If the sign of this value is positive, the orientation is counterclockwise. If the sign is negative, the orientation is clockwise.
To be precise, the above method only gives you information on which side of the polygon the diagonal lies. Obviously, the polygon can still intersect the diagonal at later points.
Basically, a diagonal can be fully inside, fully outside, both inside and outside, and possibly overlapping one or more edges in all three cases. This makes it not entirely trivial to determine what you need.
From a mathematical side, there is actually not that much difference between the inside and the outside, except for such small details as the outside having infinite area. (At least for a 2D plane; on a sphere the inside and outside of a plygon are not sharply distinguished.)
You also have a subquestion about the ordering of your polygon edges. The easiest way is to sum all angles between adjacent edges in order. This will add up to N*(pi/2). For CCW polygons, N is positive.
[edit]
Once you know the direction, and if you have none of the hard cases listed above, the question is easy. The angle p0-p1-p2 is smaller than the angle p0-p1-p3. Hence, the edge p1-p3 lies at least partially outside the polygon. And if it crosses no other edge, it obviously lies fully outside the polygon.
Angle between any two vectors is
alpha = acos(v1.x * v2.x + v1.y * v2.y)
Since you now can have the angle between
v1 and v3 = alpha1; v1 and v2 = alpha2;
You can check if alpha2 is inside alpha1:
function normalize(a):
if a > 2 * pi then a - 2 * pi
else if a < 2 * pi then a + 2 * pi
else a
alpha1 = normalize(alpha1)
alpha2 = normalize(alpha2)
if (alpha2 < alpha1) then is_between
else is_not_between
This is not very complete, but you should get the idea.
EDIT: it won't work if the polygon is overlapping as MSalters noted.

How many integer points within the three points forming a triangle?

Actually this is a classic problem as SO user Victor put it (in another SO question regarding which tasks to ask during an interview).
I couldn't do it in an hour (sigh) so what is the algorithm that calculates the number of integer points within a triangle?
EDIT: Assume that the vertices are at integer coordinates. (otherwise it becomes a problem of finding all points within the triangle and then subtracting all the floating points to be left with only the integer points; a less elegant problem).
Assuming the vertices are at integer coordinates, you can get the answer by constructing a rectangle around the triangle as explained in Kyle Schultz's An Investigation of Pick's Theorem.
For a j x k rectangle, the number of interior points is
I = (j – 1)(k – 1).
For the 5 x 3 rectangle below, there are 8 interior points.
(source: uga.edu)
For triangles with a vertical leg (j) and a horizontal leg (k) the number of interior points is given by
I = ((j – 1)(k – 1) - h) / 2
where h is the number of points interior to the rectangle that are coincident to the hypotenuse of the triangles (not the length).
(source: uga.edu)
For triangles with a vertical side or a horizontal side, the number of interior points (I) is given by
(source: uga.edu)
where j, k, h1, h2, and b are marked in the following diagram
(source: uga.edu)
Finally, the case of triangles with no vertical or horizontal sides can be split into two sub-cases, one where the area surrounding the triangle forms three triangles, and one where the surrounding area forms three triangles and a rectangle (see the diagrams below).
The number of interior points (I) in the first sub-case is given by
(source: uga.edu)
where all the variables are marked in the following diagram
(source: uga.edu)
The number of interior points (I) in the second sub-case is given by
(source: uga.edu)
where all the variables are marked in the following diagram
(source: uga.edu)
Pick's theorem (http://en.wikipedia.org/wiki/Pick%27s_theorem) states that the surface of a simple polygon placed on integer points is given by:
A = i + b/2 - 1
Here A is the surface of the triangle, i is the number of interior points and b is the number of boundary points. The number of boundary points b can be calculated easily by summing the greatest common divisor of the slopes of each line:
b = gcd(abs(p0x - p1x), abs(p0y - p1y))
+ gcd(abs(p1x - p2x), abs(p1y - p2y))
+ gcd(abs(p2x - p0x), abs(p2y - p0y))
The surface can also be calculated. For a formula which calculates the surface see https://stackoverflow.com/a/14382692/2491535 . Combining these known values i can be calculated by:
i = A + 1 - b/2
My knee-jerk reaction would be to brute-force it:
Find the maximum and minimum extent of the triangle in the x and y directions.
Loop over all combinations of integer points within those extents.
For each set of points, use one of the standard tests (Same side or Barycentric techniques, for example) to see if the point lies within the triangle. Since this sort of computation is a component of algorithms for detecting intersections between rays/line segments and triangles, you can also check this link for more info.
This is called the "Point in the Triangle" test.
Here is an article with several solutions to this problem: Point in the Triangle Test.
A common way to check if a point is in a triangle is to find the vectors connecting the point to each of the triangle's three vertices and sum the angles between those vectors. If the sum of the angles is 2*pi (360-degrees) then the point is inside the triangle, otherwise it is not.
Ok I will propose one algorithm, it won't be brilliant, but it will work.
First, we will need a point in triangle test. I propose to use the "Barycentric Technique" as explained in this excellent post:
http://www.blackpawn.com/texts/pointinpoly/default.html
Now to the algorithm:
let (x1,y1) (x2,y2) (x3,y3) be the triangle vertices
let ymin = floor(min(y1,y2,y3)) ymax = ceiling(max(y1,y2,y3)) xmin = floor(min(x1,x2,x3)) ymax = ceiling(max(x1,x2,3))
iterating from xmin to xmax and ymin to ymax you can enumerate all the integer points in the rectangular region that contains the triangle
using the point in triangle test you can test for each point in the enumeration to see if it's on the triangle.
It's simple, I think it can be programmed in less than half hour.
I only have half an answer for a non-brute-force method. If the vertices were integer, you could reduce it to figuring out how to find how many integer points the edges intersect. With that number and the area of the triangle (Heron's formula), you can use Pick's theorem to find the number of interior integer points.
Edit: for the other half, finding the integer points that intersect the edge, I suspect that it's the greatest common denominator between the x and y difference between the points minus one, or if the distance minus one if one of the x or y differences is zero.
Here's another method, not necessarily the best, but sure to impress any interviewer.
First, call the point with the lowest X co-ord 'L', the point with the highest X co-ord 'R', and the remaining point 'M' (Left, Right, and Middle).
Then, set up two instances of Bresenham's line algorithm. Parameterize one instance to draw from L to R, and the second to draw from L to M. Run the algorithms simultaneously for X = X[L] to X[M]. But instead of drawing any lines or turning on any pixels, count the pixels between the lines.
After stepping from X[L] to X[M], change the parameters of the second Bresenham to draw from M to R, then continue to run the algorithms simultaneously for X = X[M] to X[R].
This is very similar to the solution proposed by Erwin Smout 7 hours ago, but using Bresenham instead of a line-slope formula.
I think that in order to count the columns of pixels, you will need to determine whether M lies above or below the line LR, and of course special cases will arise when two points have the same X or Y co-ordinate. But by the time this comes up, your interviewer will be suitably awed and you can move on to the next question.
Quick n'dirty pseudocode:
-- Declare triangle
p1 2DPoint = (x1, y1);
p2 2DPoint = (x2, y2);
p3 2DPoint = (x3, y3);
triangle [2DPoint] := [p1, p2, p3];
-- Bounding box
xmin float = min(triangle[][0]);
xmax float = max(triangle[][0]);
ymin float = min(triangle[][1]);
ymax float = max(triangle[][1]);
result [[float]];
-- Points in bounding box might be inside the triangle
for x in xmin .. xmax {
for y in ymin .. ymax {
if a line starting in (x, y) and going in any direction crosses one, and only one, of the lines between the points in the triangle, or hits exactly one of the corners of the triangle {
result[result.count] = (x, y);
}
}
}
I have this idea -
Let A(x1, y1), B(x2, y2) and C(x3, y3) be the vertices of the triangle. Let 'count' be the number of integer points forming the triangle.
If we need the points on the triangle edges then using Euclidean Distance formula http://en.wikipedia.org/wiki/Euclidean_distance, the length of all three sides can be ascertained.
The sum of length of all three sides - 3, would give that count.
To find the number of points inside the triangle we need to use a triangle fill algorithm and instead of doing the actual rendering i.e. executing drawpixel(x,y), just go through the loops and keep updating the count as we loop though.
A triangle fill algorithm from
Fundamentals of Computer Graphics by
Peter Shirley,Michael Ashikhmin
should help. Its referred here http://www.gidforums.com/t-20838.html
cheers
I'd go like this :
Take the uppermost point of the triangle (the one with the highest Y coordinate). There are two "slopes" starting at that point. It's not the general solution, but for easy visualisation, think of one of both "going to the left" (decreasing x coordinates) and the other one "going to the right".
From those two slopes and any given Y coordinate less than the highest point, you should be able to compute the number of integer points that appear within the bounds set by the slopes. Iterating over decreasing Y coordinates, add all those number of points together.
Stop when your decreasing Y coordinates reach the second-highest point of the triangle.
You have now counted all points "above the second-highest point", and you are now left with the problem of "counting all the points within some (much smaller !!!) triangle, of which you know that its upper side parallels the X-axis.
Repeat the same procedure, but now with taking the "leftmost point" instead of the "uppermost", and with proceedding "by increasing x", instead of by "decreasing y".
After that, you are left with the problem of counting all the integer points within a, once again much smaller, triangle, of which you know that its upper side parallels the X-axis, and its left side parallels the Y-axis.
Keep repeating (recurring), until you count no points in the triangle you're left with.
(Have I now made your homework for you ?)
(wierd) pseudo-code for a bit-better-than-brute-force (it should have O(n))
i hope you understand what i mean
n=0
p1,p2,p3 = order points by xcoordinate(p1,p2,p3)
for int i between p1.x and p2.x do
a = (intersection point of the line p1-p2 and the line with x==i).y
b = (intersection point of the line p1-p3 and the line with x==i).y
n += number of integers between floats (a, b)
end
for i between p2.x+1 and p3.x do
a = (intersection point of the line p2-p3 and the line with x==i).y
b = (intersection point of the line p1-p3 and the line with x==i).y
n += number of integers between floats (a, b)
end
this algorithm is rather easy to extend for vertices of type float (only needs some round at the "for i.." part, with a special case for p2.x being integer (there, rounded down=rounded up))
and there are some opportunities for optimization in a real implementation
Here is a Python implementation of #Prabhala's solution:
from collections import namedtuple
from fractions import gcd
def get_points(vertices):
Point = namedtuple('Point', 'x,y')
vertices = [Point(x, y) for x, y in vertices]
a, b, c = vertices
triangle_area = abs((a.x - b.x) * (a.y + b.y) + (b.x - c.x) * (b.y + c.y) + (c.x - a.x) * (c.y + a.y))
triangle_area /= 2
triangle_area += 1
interior = abs(gcd(a.x - b.x, a.y - b.y)) + abs(gcd(b.x - c.x, b.y - c.y)) + abs(gcd(c.x - a.x, c.y - a.y))
interior /= 2
return triangle_area - interior
Usage:
print(get_points([(-1, -1), (1, 0), (0, 1)])) # 1
print(get_points([[2, 3], [6, 9], [10, 160]])) # 289
I found a quite useful link which clearly explains the solution to this problem. I am weak in coordinate geometry so I used this solution and coded it in Java which works (at least for the test cases I tried..)
Link
public int points(int[][] vertices){
int interiorPoints = 0;
double triangleArea = 0;
int x1 = vertices[0][0], x2 = vertices[1][0], x3 = vertices[2][0];
int y1 = vertices[0][1], y2 = vertices[1][1], y3 = vertices[2][1];
triangleArea = Math.abs(((x1-x2)*(y1+y2))
+ ((x2-x3)*(y2+y3))
+ ((x3-x1)*(y3+y1)));
triangleArea /=2;
triangleArea++;
interiorPoints = Math.abs(gcd(x1-x2,y1-y2))
+ Math.abs(gcd(x2-x3, y2-y3))
+ Math.abs(gcd(x3-x1, y3-y1));
interiorPoints /=2;
return (int)(triangleArea - interiorPoints);
}

Resources