点三角形说明

时间:2012-09-26 11:34:38

标签: php algorithm math geometry

我在三角形中找到了“点击测试”的算法和实现,例如:http://www.emanueleferonato.com/2012/06/18/algorithm-to-determine-if-a-point-is-inside-a-triangle-with-mathematics-no-hit-test-involved/,以及:http://www.blackpawn.com/texts/pointinpoly/default.html

但在我工作的项目中,我发现了这段代码:

public static function pointInTriangle($x, $y, $x1, $y1, $x2, $y2, $x3, $y3)
{   
    return self::side($x, $y, $x1, $y1, $x2, $y2, $x3, $y3) &&
           self::side($x, $y, $x1, $y1, $x3, $y3, $x2, $y2) &&
           self::side($x, $y, $x3, $y3, $x2, $y2, $x1, $y1);
}

private static function side($x, $y, $x1, $y1, $x2, $y2, $x3, $y3)
{
    if ($x1 - $x2 != 0) {
        $k    = ($y1 - $y2) / ($x1 - $x2);
        $s1   = $y3 - $y1 - $k * ($x3 - $x1);
        $s2   = $y - $y1 - $k * ($x - $x1);
    }
    else {
        $s1   = $x3 - $x1;
        $s2   = $x - $x1;
    }
    return ($s1 * $s2) >= 0;
}

你能告诉我这是如何运作的吗?为什么我们需要计算$ k(这是x1,y1和x2之间的斜率,y2点,不是吗?)?

我有理解第一条款的问题。为什么我们需要从y3中减去y1,从x3和x1减去多个k到减法结果?这个操作怎么办?什么是$ k *($ x3 - $ x1)? $ k是积分$ x1,$ y1和$ x2,$ y2之间的斜率,不在$ x1,$ y1和$ x3,$ y3之间。

我对代数几何有一些了解。换句话说,如果主公式(直线方程)是y = kx + b,对于点(x1,我们有0 = y-y1 - (y2-y1)/(x2-x1)*(x-x1) y1)和(x2,y2),然后f(x3,y3)= y3-y1 - (y2-y1)/(x2-x1)*(x3-x1)?

我是对的吗?

1 个答案:

答案 0 :(得分:5)

函数side回答问题“点 x x 3 在形成的线的同一侧通过点 x 1 x 2 “。如果 x 3 的所有三个选项的答案为“是”,则点 x 位于三角形内。

side的实施有点笨拙。看第一个条款:

if ($x1 - $x2 != 0) {
    $k    = ($y1 - $y2) / ($x1 - $x2);
    $s1   = $y3 - $y1 - $k * ($x3 - $x1);
    $s2   = $y - $y1 - $k * ($x - $x1);
}

是的,$k是从 x 1 x 2 的直线的斜率; $s1$s2分别是此行上方 x 3 x 的高度。

请看第二个条款:

else {
    $s1   = $x3 - $x1;
    $s2   = $x - $x1;
}

此处,$s1$s2具有不同的含义。它们是两条点在垂直线右侧的距离。

无论哪种方式,这个:

return ($s1 * $s2) >= 0;

给出了正确的答案。 (如果你对矢量代数感到满意的话,你会遇到一条几乎垂直的线 - 有一种更干净,更安全的方法。)

修改

让我们从第一个子句重写一行:

$ s1 = $ y3 - $ y1 - $ k *($ x3 - $ x1);
$ s1 = $ y3 - $ k *($ x3 - $ x1) - $ y1;
$ s1 = $ y3 - ($ k *($ x3 - $ x1)+ $ y1);

粗体部分是点 x 3 正下方(或上方)线上点的y坐标。因此$s1是该点上方(或下方) x 3 的高度。