2016-04-04 7 views
0

Ich mache einige Beispiele für meine Schularbeit.Bewegungspunkte mit Skalierungsgitter (Punkte in Liste)

Jetzt bin ich an einem Punkt fest. Ich werde versuchen, so litllet Code enthalten, wie ich kann, aber ich bin nicht sicher, was Sie alle brauchen ..

(sorry für Namen und coments in meiner Mutter lang einschließlich)

Heres, was ich tun muss: Ich habe mein "Malprogramm", wo Sie Punkte hinzufügen können, indem Sie auf klicken und dann Linien aneinander zeichnen. Ich programmierte ein Raster und wenn Sie ein Kontrollkästchen aktivieren, sucht es nach dem nächsten möglichen Punkt in der Raster-Liste und wendet dann seine Koordinaten auf den Punkt an, den Sie mit der Maus malen möchten.

Sie können dieses Raster auch nach Trackbar-Werten skalieren.

Jetzt kommt mein Problem: Ich muss meine gemalten Punkte mit dem Raster bewegen, wenn ich es skaliere. Ich habe keine Ahnung, da ich einfach für jeden Punkt in Gitter tun kann. X = p.X + trackbarValue. (Geting Fehler)

Hier ist mein Code für Raster und Malerei:

List<Point> rastr = new List<Point>(); //rastr means grid 
List<Point> body = new List<Point>(); //painting poits 

    private void panel1_Paint(object sender, PaintEventArgs e) 
    { 
      Graphics kp = e.Graphics; 
      foreach (Point p in body) 
      { 
       kp.FillEllipse(st, p.X-s/2, p.Y-s/2, s, s); 
      } 
      //double buffer nezapomenout 
      if (body.Count>1) 
      { 
       kp.DrawLines(pero, body.ToArray());//to array prevedeni na pole 
      } 
      for (int x = 0; x < panel1.Width; x += trackBarGrid.Value) 
       for (int y = 0; y < panel1.Height; y += trackBarGrid.Value) 
       { 
        if (showGrid == true) 
        { 
         kp.FillEllipse(grid, x-2, y-2, 4, 4); 
        } 
        Point gridpoint = new Point(x,y); 
        rastr.Add(gridpoint); 
       } 
     } 

Hier wird für die nächsten ein in Raster suchen und dann die Anwendung Koordinaten:

private void panel1_MouseClick(object sender, MouseEventArgs e) 
    { 
     if (useGrid == true) 
     { 
      //rozjedu cykly abych nasel nejblizsi bod (porovnavat jednotlivy koordinace) 
      foreach (Point p in rastr) 
      { 
       if (e.Location.X - p.X < trackBarGrid.Value/2) //kdyz odecteme pozici bodu v listu rastr.x od pozice x kliknuti nesmi byt vetsi nez polovina delky odsazeni rastrovych bodu 
        if (e.Location.Y - p.Y < trackBarGrid.Value/2) // to same jen s pozici Y 
        { 
         Point zapsat = new Point(p.X, p.Y); 
         body.Add(zapsat); //od tyhle pozice najit nejblizsi point v gridu 
         break;//bod jsme uspesne nasli. Nyni musime cyklus uzavrit aby se nezacli pridavat body ktere nechceme 
        } 
      } 
      panel1.Refresh(); 
     } 
     else { 
      body.Add(e.Location); 
      panel1.Refresh(); 
     } 
    } 

mein trackbar Veranstaltung auch:

private void trackBarGrid_Scroll(object sender, EventArgs e) 
    { 
     rastr.Clear(); 
     panel1.Refresh(); 
    } 

Und mein armer Versuch auf dieser

private void trackBarGrid_Scroll(object sender, EventArgs e) 
    { 
     foreach (Point p in rastr) 
     { 
      p.X += TrackBarValue; 
      p.Y += TrackBarValue; 
     } 
     panel1.Refresh(); 
    } 

Eine letzte Anmerkung, dass ich diese "freihändige" Malerei nicht behalten muss. Ich kann dieses Gitter einfach benutzen.

Hier sind einige Bilder ..

Before scaling

After scaling

+0

Bitte helfen Sie im verzweifelt: D –

+0

1) Bitte bearbeiten Sie Ihre Frage zu richtigen Englisch; Dies ist ein professionelles Archiv. 2) Um die Koordinaten Ihrer Punkte zu skalieren, müssen Sie multiplizieren, nicht hinzufügen. Sie müssen den Skalierungsfaktor (oder die Faktoren kennen, wenn Sie in x- und y-Richtung unterschiedlich skalieren). Dann können Sie die neuen Punkte erhalten, indem Sie die alten Werte mit den Skalierungsfaktoren multiplizieren. – TaW

Antwort

1

es gibt zwei Möglichkeiten, wie Sie gewählt haben können Sie Ihre Grafiken zu skalieren. Einer ist extrem einfach, der andere etwas involviert.

Hier ist die einfache:

Ganz einfach von der Paint Veranstaltung nach oben hinzufügen:

float scale = trackBar1.Value/100f; 
if (scale == 0) scale = 1; 
e.Graphics.ScaleTransform(scale, scale); 

Dieses etwas gewunden sieht aber die TrackBar keinen Wert haben, wenn die Paint Ereignis zuerst aufgerufen.

Das Objekt Graphics selbst ist jetzt skaliert und alles, was Sie zeichnen mit wird skaliert werden.

Das war wirklich einfach.

Ein mögliches Problem, das Sie möglicherweise haben, ist, dass alles, einschließlich der Breite eines Pen wird nach oben oder unten skaliert werden.

Sie wurden in Ihrer Frage für den beteiligten Weg zu gehen, also lassen Sie sie auch das tun ..:

Zuerst erstellen wir eine Funktion, die ein Punkt accoding die TrackBar ‚s Value skaliert. Hier ist sie:

PointF scaledPoint(PointF pt, float scale, bool unscale) 
{ 
    if (unscale) return new PointF(pt.X/scale, pt.Y/scale); 
    else return new PointF(pt.X * scale, (pt.Y * scale)); 
} 

Zwei Dinge sind bemerkenswert:

  • Die Funktion arbeitet tatsächlich mit PointF nicht Point. Dies ist sehr wichtig, da die Skalierung Präzision nicht verlieren darf! Geht man von, sagen wir 5 runter zu 33% und wieder zurück geht es nicht mehr zu 5 sondern zu 3 ..!

  • Es gibt einen zusätzlichen Parameter, der die Skalierung von einem Punkt entfernt. Wir brauchen es im Moment nicht; Aber du wirst, sobald du einen Punkt von einem MouseClick fangen willst, wenn die Skalierung eingeschaltet ist!

Jetzt verwenden wir es, um unsere Punktliste zu skalieren.

Wir könnten es direkt tun, vielleicht so:

for (int p = 0; p < body.Count; p++) 
    body[p] = scaledPoint(body[p], scale, false); 

Während dies funktioniert ist, haben ein böses Problem: Wenn wir die TrackBar bewegen wird es reapetedly gilt einen wachsenden Skalierungsfaktor . Dies bedeutet, dass die Grafik größer wird schneller und schneller ..nicht gut.

Stattdessen schaffen wir ein zweites List<PointF> bodyO mit den ursprünglichen Punktwerte, die ..

Das beibehalten müssen bedeutet, dass wir Punkte bodyO hinzufügen, aber mit body und Maßstab bodyO zu Körper ziehen ..:

void scalePoints(float scale) 
{ 
    for (int p = 0; p < body.Count; p++) 
     body[p] = scaledPoint(body0[p], scale, false); 
} 

Wir nennen so ziemlich wie in Ihrem Code:

private void trackBar1_Scroll(object sender, EventArgs e) 
{ 
    scalePoints(trackBar1.Value/100f); 
    panel1.Refresh(); 
} 

Mal sehen, wie dies in den 01 funktioniertVeranstaltung:

private void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    float scale = trackBar1.Value/100f; 
    if (scale == 0) scale = 1; 

    bool showGrid = true; // inserted for testing 

    // these graphics work with the scaled points: 
    foreach (PointF pt in body) e.Graphics.FillEllipse(Brushes.Red, 
            pt.X - 2, pt.Y - 2, scale * 4, scale * 4); 
    if (body.Count > 1) e.Graphics.DrawLines(Pens.Black, body.ToArray()); 

    // here we don't use points but calculate the coordinates, so we need to scale 
    for (int x = 0; x < panel1.Width; x += trackBar2.Value) 
     for (int y = 0; y < panel1.Height; y += trackBar2.Value) 
     { 
      if (showGrid == true) 
      { 
       e.Graphics.FillEllipse(Brushes.Gray, 
          scale * (x - 2), scale * (y - 2), scale * 4, scale * 4); 
      } 
      // Point gridpoint = new Point(x, y); // not sure what you do here..? 
      // rastr.Add(gridpoint); // maybe add the point scaled? 
     } 
} 

Bitte beachte, dass ich die Größe der Punkte als auch skaliert.Btw, machen alle beide Version gleich aussehen würden Sie die Pen wie gut skalieren müssen:

using (Pen pen = new Pen(somecolor, penWidth * scale)) 

Schließlich ist hier, wie ein neuer Punkt in der Mouseclick hinzuzufügen:

private void panel1_MouseClick(object sender, MouseEventArgs e) 
{ 
    body0.Add(scaledPoint(e.Location, trackBar1.Value/100f, true)); 
    body.Add(e.Location); 
    panel1.Invalidate(); 
} 

Wir es hinzufügen auf die ursprüngliche Liste die aktuelle Skalierung und wie es ist, dh mit der aktuellen ‚Pixelgröße‘ auf die skalierten Liste Umkehren bodyO ..

enter image description hereenter image description here

Btw: Die vielen Gitterpunkte brauchen einige Zeit ohne DoubleBuffering; dies schafft eine gewisse Flimmern .. also entweder eine PanelUnterklasse mit DoubleBuffering verwenden:

class DrawPanel : Panel 
{ 
    public DrawPanel() 
    { DoubleBuffered = true; } 
} 

Oder für ein Picturebox (empfohlen) gehen!

+0

WOW Mann: D Das habe ich nicht kommen sehen. Ich fühle mich wie es ist nicht mehr meine Arbeit xD Vielen Dank! Bin dankbar! Wird so schnell wie möglich eingeben, wenn ich es funktioniert habe. –

+0

Verdammt immer ziemlich müde und verloren dort: D Dies ist der erste Fehler, den es mir http://picpaste.com/awdawdawd-BKzQmZVG.JPG –

+0

Hehe, keine Notwendigkeit, alles zu kopieren, nur studieren Sie es ;-) - Hinweis dass ich das Gitternetz nicht ganz verstanden habe, bis ich die Frage bearbeitet habe. Es bleibt also einiges an Arbeit übrig. – TaW

0

ich sie irgendwie geschafft, jene Punkte outa dieser Liste erhalten dann bearbeiten und sie in zurückstellen. So wie Sie gesagt haben, ich habe nur um diese Skalierungsfaktoren herauszufinden. Es ist bereits in Bewegung, aber nicht im Raster. Ich sagte, es tut mir leid für mein Englisch, so wie du siehst, dass es keine Möglichkeit mehr gibt, es noch mehr zu korrigieren: Tut mir Leid ... Ich helfe mir (; lachte ein wenig über diese professionelle Archivnotiz) Einige ppl Post hier noch schlimmer Fragen als diese. D sowieso thx wieder ein bisschen es selbst gelöst Genau das, was Multiplikation :)

private void trackBarGrid_Scroll(object sender, EventArgs e) 
     { 
      if (trackBarGrid.Value > trackbarval) 
      { 
       for (int i = 0; i < body.Count; i++) 
       { 
        Point point = body[i]; 
        point.X += trackBarGrid.Value - trackbarval; 
        point.Y += trackBarGrid.Value - trackbarval; 
        body[i] = point; 
       } 
      } 
      else if (trackBarGrid.Value < trackbarval) 
      { 
       for (int i = 0; i < body.Count; i++) 
       { 
        Point point = body[i]; 
        point.X -= trackbarval- trackBarGrid.Value; 
        point.Y -= trackbarval- trackBarGrid.Value ; 
        body[i] = point; 
       } 
      } 
      rastr.Clear(); 
      panel1.Refresh(); 
      trackbarval = trackBarGrid.Value; 
     } 
+0

Nun, ich habe nicht nach Perfektion gefragt, nur ein bisschen mehr Aufwand. Das Wort ist nicht "du", nicht "out", sondern "aus" usw. Und das ist eine große Hilfe, denn es wird deine Chancen auf gute Antworten verbessern und die Gefahr von Downvotes reduzieren. - Ich bin froh, dass Sie Fortschritte gemacht haben. Ich sehe aber nicht, dass du Multiplikationen machst. Wenn Sie möchten, werde ich eine funktionierende Antwort posten. – TaW

+0

Hinweis-1 Die Trackleiste kann nur ganze Zahlen enthalten, daher sollten sie als Prozentwerte interpretiert werden, d. H. Der Skalierungsfaktor wäre trackBar.Value/100f. Tipp-2: Sie sollten PointF anstelle von Point verwenden, da Sie schnell die Präzision verlieren. Tipp-3: Für gute Ergebnisse behalten Sie eine Liste mit den ursprünglichen Punkten __und__ eins mit den skalierten Punkten; dann immer aus dem original berechnen und immer die skalierte liste zeichnen. Sonst skaliert up und down nicht yopu zurück zum original .. – TaW

+0

Okey :) Danke für die Antwort dann :) Ich werde versuchen, richtig zu tippen. –