Кривые Безье в WPF - PullRequest
       5

Кривые Безье в WPF

0 голосов
/ 30 марта 2012

Я рисую некоторые кривые Безье в 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 ]

2 голосов
/ 31 марта 2012

По дикой догадке, это, вероятно, ошибка округления.Единицы, используемые в WPF, не являются пикселями, они являются независимыми от разрешения единицами.Когда WPF на самом деле что-то рисует, он должен конвертировать эти единицы в реальные пиксели на любом экране, на котором он рисует.Если преобразование окажется на полпути между реальными пикселями, оно заштрихует эти пиксели, чтобы попытаться приблизить половину пикселя в каждом реальном пикселе.Следовательно, вы иногда получаете серые пиксели вокруг предположительно черной линии (сглаживание).

Свойство SnapsToDevicePixels может помочь вам.

1 голос
/ 31 марта 2012

Очевидно, что ошибка в алгоритме рисования.Я не лучший в WPF, но вы можете взглянуть на это сообщение в блоге.

...