WPF中的Bezier曲线

时间:2012-03-30 18:35:10

标签: wpf shapes bezier

我在WPF中绘制了一些贝塞尔曲线,并且大多数情况下它正在工作但我在每个段之间得到了一些微弱的分离。正如您所看到的,它们甚至出现在直线部分中,所以我不相信这个问题是由于段数不足造成的。 (此图像放大4倍。)

Faint separations

我正在使用System.Windows.Shapes.Line对象的集合来绘制它们。它们在代码中实例化,如:

Shapes.Line Line = new Shapes.Line();
Line.Stroke = Brush;
Line.HorizontalAlignment = Windows.HorizontalAlignment.Left;
Line.VerticalAlignment = Windows.VerticalAlignment.Center;
Line.StrokeThickness = 10;

我的理论是,这种分离是由于一条线结束的点与下一条线开始的点相同,但我不确定解决这个问题的最佳方法是什么。我是相当新的,所以我不想在我问之前是否有任何经过尝试的真实解决方案让这些微弱的分离消失之前就去黑客攻击。

修改

以下是我用于生成细分的代码。 ILine接口是我创建的,但它的点值只是稍后在程序中转换为System.Windows.Shapes.Line各自的值。

public static void FormBezier(List<ILine> Lines, Point[] pt)
{
    if (Lines.Count == 0) return;

    double t, dt, x0, y0, x1, y1;

    t = 0.0;
    dt = 1.0 / Lines.Count;
    x1 = X(t, new double[] { pt[0].X, pt[1].X, pt[2].X, pt[3].X });
    y1 = X(t, new double[] { pt[0].Y, pt[1].Y, pt[2].Y, pt[3].Y });
    t += dt;

    for(int index = 1; index < Lines.Count - 1; index++)
    {
        x0 = x1;
        y0 = y1;
        x1 = X(t, new double[] { pt[0].X, pt[1].X, pt[2].X, pt[3].X });
        y1 = X(t, new double[] { pt[0].Y, pt[1].Y, pt[2].Y, pt[3].Y });

        Lines[index].Start.X = x0;
        Lines[index].End.X = x1;
        Lines[index].Start.Y = y0;
        Lines[index].End.Y = y1;
        t += dt;
    }

    t = 1.0;
    x0 = x1;
    y0 = y1;
    x1 = X(t, new double[] { pt[0].X, pt[1].X, pt[2].X, pt[3].X });
    y1 = X(t, new double[] { pt[0].Y, pt[1].Y, pt[2].Y, pt[3].Y });
    Lines[Lines.Count - 1].Start.X = x0;
    Lines[Lines.Count - 1].End.X = x1;
    Lines[Lines.Count - 1].Start.Y = y0;
    Lines[Lines.Count - 1].End.Y = y1;
}
public static double X(double t, double[] x)
{
    return 
        x[0] * Math.Pow((1 - t), 3) + 
        x[1] * 3 * t * Math.Pow((1 - t), 2) + 
        x[2] * 3 * Math.Pow(t, 2) * (1 - t) + 
        x[3] * Math.Pow(t,  3);

}

2 个答案:

答案 0 :(得分:2)

粗略猜测,这可能是一个舍入错误。 WPF中使用的单位不是像素,它们是与分辨率无关的单位。当WPF实际绘制某些东西时,它必须将这些单位转换为它所绘制的任何屏幕上的真实像素。如果转换最终位于实像素之间的中间位置,则会对这些像素进行着色以尝试在每个实像素中近似半个像素。因此,您有时会在所谓的黑线周围获得灰色像素(抗锯齿)。

属性SnapsToDevicePixels可能会对您有所帮助。

答案 1 :(得分:1)

显然绘图算法有问题。我不是最擅长WPF,但你可能想看看this博客文章。