Count Integral points inside a Triangle
Last Updated :
30 Sep, 2022
Given three non-collinear integral points in XY plane, find the number of integral points inside the triangle formed by the three points. (A point in XY plane is said to be integral/lattice point if both its co-ordinates are integral).
Example:
Input: p = (0, 0), q = (0, 5) and r = (5,0)
Output: 6
Explanation: The points (1,1) (1,2) (1,3) (2,1) (2,2) and (3,1) are the integral points inside the triangle.
We can use the Pick’s theorem, which states that the following equation holds true for a simple Polygon.
Pick's Theorem:
A = I + (B/2) -1
A ==> Area of Polygon
B ==> Number of integral points on edges of polygon
I ==> Number of integral points inside the polygon
Using the above formula, we can deduce,
I = (2A - B + 2) / 2
We can find A (area of triangle) using below Shoelace formula.
A = 1/2 * abs(x1(y2 - y3) + x2(y3 - y1) + x3(y1 - y2))
How to find B (number of integral points on edges of a triangle)?
We can find the number of integral points between any two vertex (V1, V2) of the triangle using the following algorithm.
1. If the edge formed by joining V1 and V2 is parallel
to the X-axis, then the number of integral points
between the vertices is :
abs(V1.x - V2.x) - 1
2. Similarly, if edge is parallel to the Y-axis, then
the number of integral points in between is :
abs(V1.y - V2.y) - 1
3. Else, we can find the integral points between the
vertices using below formula:
GCD(abs(V1.x-V2.x), abs(V1.y-V2.y)) - 1
The above formula is a well known fact and can be
verified using simple geometry. (Hint: Shift the
edge such that one of the vertex lies at the Origin.)
Please refer below link for detailed explanation.
https://www.geeksforgeeks.org/number-integral-points-two-points/
Below is the implementation of the above algorithm.
C++
#include<bits/stdc++.h>
using namespace std;
class Point
{
public :
int x, y;
Point( int a=0, int b=0):x(a),y(b) {}
};
int gcd( int a, int b)
{
if (b == 0)
return a;
return gcd(b, a%b);
}
int getBoundaryCount(Point p,Point q)
{
if (p.x==q.x)
return abs (p.y - q.y) - 1;
if (p.y == q.y)
return abs (p.x - q.x) - 1;
return gcd( abs (p.x-q.x), abs (p.y-q.y)) - 1;
}
int getInternalCount(Point p, Point q, Point r)
{
int BoundaryPoints = getBoundaryCount(p, q) +
getBoundaryCount(p, r) +
getBoundaryCount(q, r) + 3;
int doubleArea = abs (p.x*(q.y - r.y) + q.x*(r.y - p.y) +
r.x*(p.y - q.y));
return (doubleArea - BoundaryPoints + 2)/2;
}
int main()
{
Point p(0, 0);
Point q(5, 0);
Point r(0, 5);
cout << "Number of integral points inside given triangle is "
<< getInternalCount(p, q, r);
return 0;
}
|
Java
class Point
{
int x, y;
public Point( int a, int b)
{
x = a;
y = b;
}
}
class GFG
{
static int gcd( int a, int b)
{
if (b == 0 )
return a;
return gcd(b, a % b);
}
static int getBoundaryCount(Point p, Point q)
{
if (p.x == q.x)
return Math.abs(p.y - q.y) - 1 ;
if (p.y == q.y)
return Math.abs(p.x - q.x) - 1 ;
return gcd(Math.abs(p.x - q.x),
Math.abs(p.y - q.y)) - 1 ;
}
static int getInternalCount(Point p, Point q, Point r)
{
int BoundaryPoints = getBoundaryCount(p, q) +
getBoundaryCount(p, r) +
getBoundaryCount(q, r) + 3 ;
int doubleArea = Math.abs(p.x * (q.y - r.y) +
q.x * (r.y - p.y) +
r.x * (p.y - q.y));
return (doubleArea - BoundaryPoints + 2 ) / 2 ;
}
public static void main(String[] args)
{
Point p = new Point( 0 , 0 );
Point q = new Point( 5 , 0 );
Point r = new Point( 0 , 5 );
System.out.println( "Number of integral points" +
" inside given triangle is " +
getInternalCount(p, q, r));
}
}
|
Python3
class Point:
def __init__( self , x, y):
self .x = x
self .y = y
def gcd(a, b):
if (b = = 0 ):
return a
return gcd(b, a % b)
def getBoundaryCount(p, q):
if (p.x = = q.x):
return abs (p.y - q.y) - 1
if (p.y = = q.y):
return abs (p.x - q.x) - 1
return gcd( abs (p.x - q.x),
abs (p.y - q.y)) - 1
def getInternalCount(p, q, r):
BoundaryPoints = (getBoundaryCount(p, q) +
getBoundaryCount(p, r) +
getBoundaryCount(q, r) + 3 )
doubleArea = abs (p.x * (q.y - r.y) +
q.x * (r.y - p.y) +
r.x * (p.y - q.y))
return (doubleArea - BoundaryPoints + 2 ) / / 2
if __name__ = = "__main__" :
p = Point( 0 , 0 )
q = Point( 5 , 0 )
r = Point( 0 , 5 )
print ( "Number of integral points "
"inside given triangle is " ,
getInternalCount(p, q, r))
|
C#
using System;
public class Point
{
public int x, y;
public Point( int a, int b)
{
x = a;
y = b;
}
}
class GFG
{
static int gcd( int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
static int getBoundaryCount(Point p, Point q)
{
if (p.x == q.x)
return Math.Abs(p.y - q.y) - 1;
if (p.y == q.y)
return Math.Abs(p.x - q.x) - 1;
return gcd(Math.Abs(p.x - q.x),
Math.Abs(p.y - q.y)) - 1;
}
static int getInternalCount(Point p, Point q, Point r)
{
int BoundaryPoints = getBoundaryCount(p, q) +
getBoundaryCount(p, r) +
getBoundaryCount(q, r) + 3;
int doubleArea = Math.Abs(p.x * (q.y - r.y) +
q.x * (r.y - p.y) +
r.x * (p.y - q.y));
return (doubleArea - BoundaryPoints + 2) / 2;
}
public static void Main(String[] args)
{
Point p = new Point(0, 0);
Point q = new Point(5, 0);
Point r = new Point(0, 5);
Console.WriteLine( "Number of integral points" +
" inside given triangle is " +
getInternalCount(p, q, r));
}
}
|
Javascript
<script>
class Point
{
constructor(a,b)
{
this .x=a;
this .y=b;
}
}
function gcd(a,b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
function getBoundaryCount(p,q)
{
if (p.x == q.x)
return Math.abs(p.y - q.y) - 1;
if (p.y == q.y)
return Math.abs(p.x - q.x) - 1;
return gcd(Math.abs(p.x - q.x),
Math.abs(p.y - q.y)) - 1;
}
function getInternalCount(p,q,r)
{
let BoundaryPoints = getBoundaryCount(p, q) +
getBoundaryCount(p, r) +
getBoundaryCount(q, r) + 3;
let doubleArea = Math.abs(p.x * (q.y - r.y) +
q.x * (r.y - p.y) +
r.x * (p.y - q.y));
return (doubleArea - BoundaryPoints + 2) / 2;
}
let p = new Point(0, 0);
let q = new Point(5, 0);
let r = new Point(0, 5);
document.write( "Number of integral points" +
" inside given triangle is " +
getInternalCount(p, q, r));
</script>
|
Output:
Number of integral points inside given triangle is 6
Time Complexity: O(log(min(a,b))), as we are using recursion to find the GCD.
Auxiliary Space: O(log(min(a,b))), for recursive stack space.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...