.net版 二维平面上判断点在三角形内的最优算法
作者:叶飞影 来源:cnblogs 发布时间:2014-10-31 查看数:21793
园子里有很多关于点是否在三角形内的文章,提供了各种方法。这让人很纠结,到底该用哪种算法?这里提供一套我认为最优的算法。如果你有不同的意见,亦或有更好的算法,欢迎来讨论。
算法使用的是同向法,其原理是:假设点P位于三角形ABC内,会有这样一个规律:三角形的每一个边,其对角点与P在边的同一侧;或者说三角形的每一个顶点与P在其对角边的同一侧。
一、代码
public class Vec2
{
public float x, y;
public Vec2()
{
x = 0.0f;
y = 0.0f;
}
public Vec2(float fx, float fy)
{
x = fx;
y = fy;
}
// Add
public static Vec2 operator +(Vec2 x, Vec2 y)
{
return new Vec2(x.x + y.x, y.y + y.y);
}
public static Vec2 operator -(Vec2 x, Vec2 y)
{
return new Vec2(x.x - y.x, y.y - y.y);
}
}
public class Vec2Helper
{
// Dot product
public static float Vec2Dot(Vec2 v1, Vec2 v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
// Cross product
public static float Vec2Cross(Vec2 v1, Vec2 v2)
{
return v1.x * v2.y - v1.y * v2.x;
}
// Determine whether two vectors v1 and v2 point to the same direction
// 判断C和P在直线AB的同一侧
public static bool IsSameSide(Vec2 A, Vec2 B, Vec2 C, Vec2 P)
{
Vec2 AB = B - A;
Vec2 AC = C - A;
Vec2 AP = P - A;
float f1 = Vec2Cross(AB, AC);
float f2 = Vec2Cross(AB, AP);
// f1 and f2 should to the same direction
return f1 * f2 >= 0.0f;
}
// Same side method
// Determine whether point P in triangle ABC
public static bool IsPointInTriangle(Vec2 A, Vec2 B, Vec2 C, Vec2 P)
{
return IsSameSide(A, B, C, P) &&
IsSameSide(B, C, A, P) &&
IsSameSide(C, A, B, P);
}
// Determine whether point P in angle ABC
// 点P是否在角ABC内
public static bool IsPointInAngle(Vec2 A, Vec2 B, Vec2 C, Vec2 P)
{
return IsSameSide(A, B, C, P) && IsSameSide(B, C, A, P);
}
}
注:以上代码是本站根据原文修改成的C#版代码,原文代码请见文章末尾的连接地址。
二、测试效果
我生成一幅1024*1024大小的图像,并设置三个顶点,对图像中的所有像素调用IsPointInAngle函数,以测试其效率:
图中显示出图像生成时间为868.758毫秒,这是DEBUG版本的(注,此时间是作者统计的时间)。
本文来源:http://www.cnblogs.com/WhyEngine/p/4064686.html