给定 XY 平面中三个非共线的积分点,求出这三个点所形成的三角形内的积分点数。(如果 XY 平面上的一个点的两个坐标都是积分的,则该点被称为积分点/格点)。
例子:
输入: p = (0, 0), q = (0, 5) 和 r = (5,0)
输出: 6
解释:点 (1,1) (1,2) (1,3) (2,1) (2,2) 和 (3,1) 是三角形内的积分点。
我们可以使用Pick 定理,该定理指出以下等式对于简单多边形成立。
Pick 定理:
A = I + (B/2) -1
A ==> 多边形面积
B ==> 多边形边上的积分点数
I ==> 多边形内部的积分点数
利用上述公式,我们可以得出,
I = (2A - B + 2) / 2
我们可以使用下面的鞋带公式找到A(三角形面积)。
A = 1/2 * abs(x1(y2 - y3) + x2(y3 - y1) + x3(y1 - y2))
如何求B(三角形边上的积分点数)?
我们可以使用以下算法找到三角形任意两个顶点(V1,V2)之间的积分点数。
1. 如果 V1 和 V2 连接形成的边平行于 X 轴,则
顶点之间的
积分点数为:
abs(V1.x - V2.x) - 1
2. 类似地,如果边平行于 Y 轴,则
中间的积分点数为:
abs(V1.y - V2.y) - 1
3. 否则,我们可以
使用以下公式找到顶点之间的积分点:GCD(abs(V1.x-V2.x), abs(V1.y-V2.y)) - 1
上述公式是众所周知的事实,可以
使用简单的几何来验证。(提示:移动
边,使得其中一个顶点位于原点。)
详细解释请参阅以下链接:
javascript 两点之间的积分点数(Number of Integral Points between Two Points)
javascript 两点之间的积分点数(Number of Integral Points between Two Points)-CSDN博客
C# 两点之间的积分点数(Number of Integral Points between Two Points)
C# 两点之间的积分点数(Number of Integral Points between Two Points)-CSDN博客
Python 两点之间的积分点数(Number of Integral Points between Two Points)
Python 两点之间的积分点数(Number of Integral Points between Two Points)-CSDN博客
Java 两点之间的积分点数(Number of Integral Points between Two Points)
Java 两点之间的积分点数(Number of Integral Points between Two Points)-CSDN博客
C++ 两点之间的积分点数(Number of Integral Points between Two Points)
C++ 两点之间的积分点数(Number of Integral Points between Two Points)-CSDN博客
下面是上述算法的实现:
// JavaScript program to find Integral points inside a triangle
// Class to represent an Integral point on XY plane.
class Point
{
constructor(a,b)
{
this.x=a;
this.y=b;
}
}
// utility function to find GCD of two numbers
// GCD of a and b
function gcd(a,b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
// Finds the no. of Integral points between
// two given points.
function getBoundaryCount(p,q)
{
// Check if line parallel to axes
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;
}
// Returns count of points inside the triangle
function getInternalCount(p,q,r)
{
// 3 extra integer points for the vertices
let BoundaryPoints = getBoundaryCount(p, q) +
getBoundaryCount(p, r) +
getBoundaryCount(q, r) + 3;
// Calculate 2*A for the triangle
let doubleArea = Math.abs(p.x * (q.y - r.y) +
q.x * (r.y - p.y) +
r.x * (p.y - q.y));
// Use Pick's theorem to calculate
// the no. of Interior points
return (doubleArea - BoundaryPoints + 2) / 2;
}
// Driver Code
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));
// This code is contributed by rag2127
输出:
给定三角形内的积分点数为 6
时间复杂度: O(log(min(a,b))),因为我们使用递归来查找 GCD。
辅助空间: O(log(min(a,b))),用于递归堆栈空间。