Frage

Ich bin das Zeichnen von Grafiken in eine WinForms Picturebox. Jetzt habe ich die Suche nach einer Möglichkeit zu ‚Duplikat‘ eine Linie (ein Array von Punkten), so dass die beiden resultierenden Linien in einem festen Abstand weg von dem Original angeordnet sind. Wie in diesem Bild habe ich die rote Linie und will die schwarzen bekommen:

Bild von Linien http://img227.imageshack.us/img227/2341/ linesb.png

Ich dachte nur Bewegen der Linie ein paar Pixel nach oben / rechts / oben rechts, aber das führt zu seltsamen überlappende Linien.

Gibt es einen anderen Ansatz, der das tut, was ich will? Irgendwelche Ideen wäre sehr dankbar. Dank!

War es hilfreich?

Lösung

Ich habe eine Funktion erstellt, das tut genau , was Sie ein paar Monate brauchen vor als Teil eines Graphen Layouten Algorithmus. Ich schrieb, dass in Python und PyQt. Ich klebte nur den Code hier bei Codepad . Das sollte zu c # sehr leicht translateable sein.

Update:

übersetzt es eine Eins-zu-eins von meinem Python-Schnipsel (Liebe, die Grafiken Sachen zu tun :)). Da mein Original-Code für mehr als zwei Ausgangsleitungen entworfen wurde, nahm ich nur, dass in als auch die c # -Version. Für zwei Zeilen schwarz 20 Pixel entfernt von dem roten sind, passiert nur width = 40 und num = 2. Der zurück gezackte Array stellt eine Anordnung von Leitungen (äußerte Array), wobei jede Linie durch eine Reihe von Punkten dargestellt (innerer).

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;
}

, um es auszuprobieren ich diese kleine Probe nahm (Die gleiche Probe wie in meinem PyQt-Code):

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);
}

, die in dieser Grafik Folge:

Umrisse um die Linie http://img41.imageshack.us/img41/8606/lines2 .th.png

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top