Pregunta

Estoy dibujando gráficas en un Cuadro de imagen de Windows Forms. Ahora estoy buscando la posibilidad de una línea 'duplicado' (una matriz de puntos), de modo que las dos líneas resultantes se colocan a una distancia fija lejos de la original. Al igual que en esta imagen, tengo la línea roja y quiero conseguir el color negro:

Cuadro de líneas http://img227.imageshack.us/img227/2341/ linesb.png

pensé en sólo mover la línea de unos pocos píxeles hacia arriba / derecha / arriba-derecha, sino que conduce a la superposición de líneas extrañas.

¿Hay algún otro enfoque que hace lo que yo quiero? Cualquier idea sería muy apreciada. Gracias!

¿Fue útil?

Solución

He creado una función que hace exactamente lo que necesita hace unos meses como parte de un algoritmo de maquetación gráfica. Escribí que en Python y PyQt. Me acaba de pegar el código aquí en la pantalla de códigos . Eso debería ser muy fácil traducible a C #.

Actualización:

tradujo uno-a-uno de mi fragmento de pitón (Amor a hacer esas cosas gráficos :)). Como mi código original fue diseñado para más de dos líneas de salida, acabo de tomar eso en la versión C # también. Para dos líneas negras son 20 píxeles de distancia desde el rojo, sólo tiene que pasar width = 40 y num = 2. La matriz escalonada devuelto representa una disposición de líneas (array exterior), con cada línea representada por una matriz de puntos (interior).

public PointF[][] MultiplyLine(PointF[] line, int width, int num)
{
    if (num == 1) return new PointF[][] { line };
    if (num < 1) throw new ArgumentOutOfRangeException();
    if (line.Length < 2) return Enumerable.Range(0, num)
                  .Select(x => line).ToArray();

    Func<float, float, PointF> normVec = (x, y) => {
        float len = (float)Math.Sqrt((double)(x * x + y * y));
        return len == 0 ? new PointF(1f, 0f) : new PointF(x / len, y / len);
    };

    PointF[][] newLines = Enumerable.Range(0, num)
                  .Select(x => new PointF[line.Length]).ToArray();

    float numinv = 1f / (float)(num - 1), cor = 0f;
    PointF vec1 = PointF.Empty, vec2 = PointF.Empty, vec3 = PointF.Empty;

    int j = -1, i = -1;
    foreach (PointF p in line)
    {
        bool first = j == -1, last = j == line.Length - 2; j++;

        if (!last)
            vec1 = normVec(line[j + 1].Y - p.Y, -line[j + 1].X + p.X);
        if (!first)
            vec2 = normVec(-line[j - 1].Y + p.Y, line[j - 1].X - p.X);
        if (!first && !last)
        {
            vec3 = normVec(vec1.X + vec2.X, vec1.Y + vec2.Y);
            cor = (float)Math.Sin((Math.PI - 
                  Math.Acos(vec1.X * vec2.X + vec1.Y * vec2.Y)) / 2);
            cor = cor == 0 ? 1 : cor;
            vec3 = new PointF(vec3.X / cor, vec3.Y / cor);
        }

        i = -1;
        foreach (PointF[] newLine in newLines)
        {
            i++; cor = (float)width * ((float)i * numinv - 0.5f);
            vec1 = first ? vec1 : last ? vec2 : vec3;
            newLine[j] = new PointF(vec1.X * cor + p.X, vec1.Y * cor + p.Y);
        }
    }

    return newLines;
}

Para probarlo Tomé esta pequeña muestra (la misma muestra que en mi código PyQt):

PointF[] pts = new PointF[] { 
    new PointF(100f, 100f), new PointF(300f, 200f), 
    new PointF(500f, 200f), new PointF(300f, 500f), 
    new PointF(600f, 450f), new PointF(650f, 180f), 
    new PointF(800f, 180f), new PointF(800f, 500f), 
    new PointF(200f, 700f)
};

pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
using(Graphics g = Graphics.FromImage(pictureBox1.Image)){
    g.DrawLines(new Pen(Color.Red), pts);

    foreach (PointF[] line in MultiplyLine(pts, 80, 14))
        g.DrawLines(new Pen(Color.Black), line);
}

Lo que resultó en este gráfico:

contornos alrededor de la línea http://img41.imageshack.us/img41/8606/lines2 .th.png

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top