Actionscript 3 平行四边形包含点
判断一个点是否在平行四边形/菱形内的最快方法是什么?想象一条光线从你的点向一个方向发射。如果光线与形状的线条相交奇数次,则它位于形状内部。如果它穿过偶数次,它就在形状之外 所以在你的程序中,你只需要创建一条看不见的线,看看它有多频繁地穿过。我想,Actionscript可能有一个内置函数来完成这项工作Actionscript 3 平行四边形包含点,actionscript-3,performance,math,mathematical-optimization,Actionscript 3,Performance,Math,Mathematical Optimization,判断一个点是否在平行四边形/菱形内的最快方法是什么?想象一条光线从你的点向一个方向发射。如果光线与形状的线条相交奇数次,则它位于形状内部。如果它穿过偶数次,它就在形状之外 所以在你的程序中,你只需要创建一条看不见的线,看看它有多频繁地穿过。我想,Actionscript可能有一个内置函数来完成这项工作 现在,如果你有大量的对象,而点只能在一个对象中,你可以通过使用存储对象的位置来加快速度。这样,你就不必将你的点与每一个单独的物体进行比较,只需将它附近的物体进行比较。y坐标是最简单的,所以从这个开
现在,如果你有大量的对象,而点只能在一个对象中,你可以通过使用存储对象的位置来加快速度。这样,你就不必将你的点与每一个单独的物体进行比较,只需将它附近的物体进行比较。y坐标是最简单的,所以从这个开始。如果点的y坐标在形状的顶部和底部之间,请转到x坐标。在点的y坐标处计算形状左右两侧的x坐标,并检查点的x坐标是否在它们之间 编辑: 给定左上角、右上角、右下角和左下角的四个坐标:
if (y >= y1 && y <= y3) {
var k = (x4 - x1) / (y4 - y1);
var m = x1 - k * y1;
if (x >= k * y + m) {
k = (x3 - x2) / (y3 - y2);
m = x2 - k * y2;
if (x <= k * y + m) {
// inside
}
}
}
如果(y>=y1&&y=k*y+m){
k=(x3-x2)/(y3-y2);
m=x2-k*y2;
如果(x看到我的答案,这很相似。在平行四边形的一个角位于(0,0)
的情况下,我给出了一个非常简单的测试,因为它使解释更容易理解,但一般来说修改它并不困难
编辑:由于问题负责人熟悉向量,我基本上会用这种语言重写我的答案。假设平行四边形由向量PQ
和PR
组成,其中p
、Q
和R
是角。符号*
将表示点积。选择一个点Q
PQ
垂直于PQ
(即PQ*PQ=0
)和PR*PQ>0
(例如,您可以通过将q
绕P
旋转90度来获得q
)。也选择一个点r
,这样PR*PR=0
和PQ*PR>0
。然后,当且仅当(0
我对这个问题的第一个观察是,一个矩形(与轴对齐)是一个简单的退化情况。如果矩形的两个角是:(x1,y1)和(x2,y2),那么你只需测试,给定一个点(x3,y3),min(x1,x2)
这也可能是一个有用的优化。如果我们找到平行四边形的轴对齐的边界矩形,那么我们可以从快速测试任何给定点开始
如果我们的平行线具有非零斜率,那么我们计算边界线的轴交点以及在这些斜率处通过相关点的线的交点。如果我们的两个点的交点(由两个斜率定义)在我们的边界线的交叉点之间,那么我们就在其中。如果这两者中的任何一个超出了这些范围,那么我们就不在其中
我没有时间编写一个例子,但计算这些坡度和交点是第一年的代数
[增编]
我现在明白了,第一篇文章(关于射线从被测点开始沿着任意斜率延伸)是对任何闭合平面多边形,或者,事实上,任何闭合平面曲线,这个问题的一般解决方案的参考。对于闭合曲面,它也可以延伸到三维
然而,有一个警告适用于平行四边形或菱形。对于凹多边形(或其他一些曲线),如果光线击中任何顶点(角),则测试可能返回偶数个“线”交叉。换句话说,“曲线”的任何部分同时包含在多个“边”中多边形的一部分可能返回假阳性
这有两种解决方案:明确测试线段界限(角点/顶点)处的交点,或将每条线段视为一端以(点+ε)为界(这样我们的计算就不会在任何两条边之间找到任何共同点)
我找到一个边界矩形的想法仍然是一个有用的快速测试,并且通常扩展到所有多边形。我们找到min()和max()x来找到左右边界边,以及min()和max()它还可以扩展到三维……一位朋友告诉我,标准图形库在大多数虚拟现实和MMORPG等中广泛使用它进行碰撞检测。当在边界框中查找碰撞时,它们会对包含的多边形进行更细粒度的计算有意思的是,如果你采用表达式ax+bx+c,并对给定特定直线的a、b、c点x、y求值,你会发现表达式将平面分成两半,其中一半的表达式大于零,另一半的表达式等于零少一点
现在,如果你取平行四边形的四个点,计算出构成平行四边形边的每一条直线的a,b,c系数,你可以计算所讨论的x,y的每一个表达式,并找出该点在每一条直线的哪一边。平行四边形的内部将是一个逻辑和特定边
也就是说,一旦你对四条线中的每一条都有了a,b,c,你就可以做一个类似这样的测试
if((a1*x+b1*y+c1)>0)和((a2*x+b2*y+c2)再次向大家问好,谢谢大家的回答。同时,我自己也想出了一些我认为会很快的办法:
假设我们有一个平行四边形,由PQ和PR跨越,其中PQ和PR是向量
if ( ((a1*x+b1*y+c1)>0) && ((a2*x+b2*y+c2)<0) &&
((a3*x+b3*y+c3)<0) && ((a4*x+b4*y+c4)>0) {
// it's in!
}
PA=n*PQ+m*PR
n = -det(PA, PQ)/det(PQ, PR)
m = det(PA, PR)/det(PQ, PR)
det(PA, PQ) = PA.x*PQ.y-PQ.x*PA.y
var d:Number = det(PQ, PR);
if (0 <= -det(PA, PQ)/d <= 1 && 0 <= det(PA, PR)/d <= 1)
{
//inside
}
else
{
//outside
}
T(a, b) = A + a * AB + b * AC
R(t) = O + t * D
O + t * D = A + a * AB + b * AC