我主要把這件事扔到那裏,因爲這個問題引起了我的興趣,這是我沒有專門知識,我想討論。
我拿了Point in Polygon pseudo-code,並試圖讓它適合你的情況。看起來你只是想確定一些東西是順時針還是逆時針纏繞的。這裏有一個簡單的測試和一個非常簡單的(邊緣粗糙的)C#實現。
[Test]
public void Test_DetermineWindingDirection()
{
GraphicsPath path = new GraphicsPath();
// Set up points collection
PointF[] pts = new[] {new PointF(10, 60),
new PointF(50, 110),
new PointF(90, 60)};
path.AddLines(pts);
foreach(var point in path.PathPoints)
{
Console.WriteLine("X: {0}, Y: {1}",point.X, point.Y);
}
WindingDirection windingVal = DetermineWindingDirection(path.PathPoints);
Console.WriteLine("Winding value: {0}", windingVal);
Assert.AreEqual(WindingDirection.Clockwise, windingVal);
path.Reverse();
foreach(var point in path.PathPoints)
{
Console.WriteLine("X: {0}, Y: {1}",point.X, point.Y);
}
windingVal = DetermineWindingDirection(path.PathPoints);
Console.WriteLine("Winding value: {0}", windingVal);
Assert.AreEqual(WindingDirection.CounterClockWise, windingVal);
}
public enum WindingDirection
{
Clockwise,
CounterClockWise
}
public static WindingDirection DetermineWindingDirection(PointF[] polygon)
{
// find a point in the middle
float middleX = polygon.Average(p => p.X);
float middleY = polygon.Average(p => p.Y);
var pointInPolygon = new PointF(middleX, middleY);
Console.WriteLine("MiddlePoint = {0}", pointInPolygon);
double w = 0;
var points = polygon.Select(point =>
{
var newPoint = new PointF(point.X - pointInPolygon.X, point.Y - pointInPolygon.Y);
Console.WriteLine("New Point: {0}", newPoint);
return newPoint;
}).ToList();
for (int i = 0; i < points.Count; i++)
{
var secondPoint = i + 1 == points.Count ? 0 : i + 1;
double X = points[i].X;
double Xp1 = points[secondPoint].X;
double Y = points[i].Y;
double Yp1 = points[secondPoint].Y;
if (Y * Yp1 < 0)
{
double r = X + ((Y * (Xp1 - X))/(Y - Yp1));
if (r > 0)
if (Y < 0)
w = w + 1;
else
w = w - 1;
}
else if ((Y == 0) && (X > 0))
{
if (Yp1 > 0)
w = w + .5;
else
w = w - .5;
}
else if ((Yp1 == 0) && (Xp1 > 0))
{
if (Y < 0)
w = w + .5;
else
w = w - .5;
}
}
return w > 0 ? WindingDirection.ClockWise : WindingDirection.CounterClockwise;
}
,我已經擺在那的不同使得這個特定於您的問題的一點是,我從所有點計算X和Y的平均值,並用其作爲「點面」值。所以,只傳入一些點數,它會在它們中間找到一些東西。
,我也做了這樣的假設V I + 1應該當它到達的點陣列,這樣
if (i + 1 == points.Count)
// use points[0] instead
這並沒有經過優化的邊界環繞,它只是東西可能會回答你的問題。也許你已經自己想出了這個。
在這裏我們希望爲有建設性的批評。 :)
我覺得這個問題惡化到不得不找一個內點。對於凸多邊形來說這很容易。 – 2010-11-17 21:03:10