JavaScript 计算三角形内的积分点(Count Integral points inside a Triangle)

         给定 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))),用于递归堆栈空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn_aspnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值