我需要创建用于确定如果GraphicsPath是伤口顺时针或逆时针一个GraphicsPath对象的扩展方法。

像这样:

    public static bool IsClockwise(GraphicsPath gp)
    {
        bool bClockWise = false;
        PointF[] pts = gp.PathPoints;

        foreach (PointF pt in pts)
        {
            //??
        }

        return bClockWise;
    }

请注意:我只是认为我们需要对在foreach的点GraphicsPath这里,但如果有更好的办法,请随时报价

这样做的原因是因为FillModeGraphicsPath确定是否相邻GraphicsPaths的重叠部分是“填充”(Winding)或“洞”(Alternate)。然而,如果相邻GraphicsPaths都在相同方向上缠绕这仅仅是真实的。

“FILLMODE绕组VS替代”

如果两个路径缠绕在相反方向上,即使设置FillModeWinding导致(不想要的)的孔。

有趣的是,GraphicsPath的确实有.Reverse()方法,它允许一个改变路径的方向(这确实解决该问题),但它不可能知道什么时候需要的GraphicsPath不知道的方向上.Reversed路径。

您可以帮忙与此扩展方法是什么?

有帮助吗?

解决方案

我主要抛出了这一点,因为有这个问题引起了我的兴趣,这是我在没有专业知识,我想生成讨论。

我把点在多边形伪代码并试图使其适合你的情况。似乎你只能在确定的东西是绕顺时针或逆时针感兴趣。下面是一个简单的测试和非常简单(周围的边缘粗糙)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

这还没有得到优化,这只是一些潜在的回答你的问题。也许你已经来到了这个自己。

在这里我们希望进行建设性的批评。 :)

其他提示

没有,则必须遍历所有的点来确定缠绕顺序。有许多的网页,例如在算法。

http://www.engr.colostate.edu/~ DGA / DGA /纸/ point_in_polygon.pdf

我认为,当我需要执行它,我使用从图形宝石书籍的算法,修改为地球表面(地理空间应用程序)。从我的头顶,我认为它乘以分量矢量和总结他们。总的符号给你的缠绕顺序。

修改

忽略所有这下方。我发现这个问题。

上面的代码的最后一行应当从变化:

return w > 0 ? WindingDirection.CounterClockWise : WindingDirection.Clockwise;

return w > 0 ? WindingDirection.ClockWise : WindingDirection.CounterClockwise;

否则,代码的伟大工程,我已经接受了这个作为答案(但我确实想给道具@winwaed谁发现与算法的文章)。

--- ---忽略(历史的目的只)

戴夫您好,

我不知道发生了什么(还),但我正在逐渐“顺时针”从功能是逆时针轮廓不正确的响应。

下面是轮廓,在Inkscape中0.48,其中有一个(新)选项以显示与小的半箭头头的路径的方向上显示中的一个。正如可以看到,外蜿蜒路径逆时针(即使该函数返回的顺时针方向)。

“逆时针绕线”

我要看看这个即将...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top