DrawArc, aber wie?

KarlPichler

Mitglied
Hallo liebes Forum,

Habe eine Frage zu DrawArc:

Programm Erklärung:

Der User hat zwei Buttons zur Auswahl: STRAIGHT od. CURVE.
Es muss immer eine Straight auf eine Kurve folgen (dann wieder Kurve und wieder Straight, etc .. )

Die Straight muss immer der Kurve folgen, sprich im selben Winkel weiter gezeichnet werden!

Ich habe nun ein FrameBegin Array und FramEnd Array, wo ich immer die Anfangswerte und die Endwerte eines Teilstückes abspeichere.

Mit diesen beiden Arrays möchte ich danach die Gesamte Bahn zeichnen!

Diese Punkte sind mit den färbigen Kreuzen gekennzeichnet.

Das funktioniert auch soweit gut! Allerdings weis ich nicht wirklich wie ich nun die Kurve zeichen muss, bzw. auf die Werte komme die ich für den DrawArc Befehl brauche.

d.jpg

Also ich möchte den Punkt "Pinkes Kreuz" mit dem Punkt "blaues Kreuz" mit einem DrawArc (od. vl. mit einem anderen) verbinden!

Ich hoffe das Bild hilt euch weiter.

Nun folgt der Code wie ich die Koordinaten berechne:

Code:
  public void GetNewFrameStraight(int index, FrameXYA[] frames, int origin, int length)
        {
            
            if (index == 0)
            {
                frames[index].XStart = 0;
                frames[index].YStart = 0;
                frames[index].AngleStart = alpha;
            }
            if (index > 0)
            {
                frames[index].XStart = frames[index - 1].XEnd;
                frames[index].YStart = frames[index - 1].YEnd;
                frames[index].AngleStart = frames[index - 1].AngleEnd;
            }

            frames[index].XEnd = frames[index].XStart + (float) Math.Cos(frames[index].AngleStart * Math.PI / 180.0) * length;
            frames[index].YEnd = frames[index].YStart + (float) Math.Sin(frames[index].AngleStart * Math.PI / 180.0) * length;
            frames[index].AngleEnd = frames[index].AngleStart;
            frames[index].Typ = 0;
            frames[index].Id = (float)index;
            
    }


        public void GetNewFrameCurve(int index, FrameXYA[] frames, int radius, int angle)
        {
            Vector3 v1 = new Vector3();
            
            
            if (index > 0)
            {
                frames[index].XStart = frames[index - 1].XEnd;
                frames[index].YStart = frames[index - 1].YEnd;
                frames[index].AngleStart = frames[index - 1].AngleEnd;
            }
            if (angle >= 0.0)
            {
                v1.X = (float)Math.Sin(angle * Math.PI / 180.0) * radius;   
                v1.Y = (float)-(1.0 - Math.Cos(angle * Math.PI / 180.0)) * radius;
            }
            else
            {
                v1.X = (float)-Math.Sin(angle * Math.PI / 180.0) * radius;
                v1.Y = (float)(1.0 - Math.Cos(angle * Math.PI / 180.0)) * radius;
            }

            frames[index].XEnd = ((frames[index].XStart + (float)(v1.X * Math.Cos(frames[index].AngleStart * Math.PI / 180.0) - v1.Y * (float)Math.Sin(frames[index].AngleStart * (float)Math.PI / 180.0))));
            frames[index].YEnd = ((frames[index].YStart + (float)(v1.X * Math.Sin(frames[index].AngleStart * Math.PI / 180.0) + v1.Y * (float)Math.Cos(frames[index].AngleStart * (float)Math.PI / 180.0))));

         
            frames[index].AngleEnd = (frames[index].AngleStart- angle);
            frames[index].Typ = 1;
            frames[index].Id = (float)index;

        }

Bitte helft mir, i versuche es schon ziemlich lange, aber ich komme nicht drauf!

Lg
 

KarlPichler

Mitglied
ja stimmt, hab aber auch geschrieben das ichs nicht kapier, und bat dich um ein wenig code!

mir fehlt total die logik! sorry für meine dummheit^^

lg und danke
 

KarlPichler

Mitglied
Hallo wieder mal,

@Shakie, hab jetzt wieder mal einen kleinen schritt in richtung ziel geschafft! Allerdings habe ich weiterhin riesen Probleme mit dem DrawArcBefehl.

Hier mal der Code, den ich verwende um den X, Y für den DrawArc Befehl auszurechnen.


Code:
          radius = /*(Prexe - Prexs)*/ frames[j].Radius / 20 * (float)iZoomFactor;

                    Vector3 vecToRadius;
                    if (frames[j].Angle >= 0.0)
                        vecToRadius = new Vector3(-radius, -2.0 * radius, 0);
                    else
                        vecToRadius = new Vector3(-radius, 2.0 * radius, 0);

                    vecToRadius.Roll(frames[j-1].AngleEnd); // angle prev section

                    vecToRadius += new Vector3(Prexe, Preye, 0);

Die Vector Klasse hab ich theCodeProject! d2.jpg

Im folgenden Bild kannst du mein Problem erkennen! Der erste Kreis stimmt noch, aber eben zufällig. Der zweite ist schon falsch!
Negative werte für width und height sind ja bei DrawArc nicht möglich od.?
Wie dreh ich nun den DrawArc bzw. was soll ich drehen um das gewünschte Ergebniss zu erhalten?

Lg und Danke
 

Shakie

Erfahrenes Mitglied
@Vektor: Im .Net-Framework gibt es auch eine Vektor3D-Klasse, nämlich im System.Windows.Media.Media3D-Namespace, siehe hier.
Es spricht aber natürlich nichts dagegen die Vektor-Klasse von CodeProject zu verwenden.

@DrawArc: Ich weiß nicht wie ich es anders erklären soll...
Um vom pinken zum gelben Punkt zu gelangen benötigst du zum Beispiel diese drei Vektoren:
  • vecA: Vektor vom Koordinatenursprung (0,0) zum gelben Punkt
  • vecB: Vektor vom gelben Punkt zum Kreismittelpunkt
  • vecC: Vektor vom Kreismittelpunkt zur oberen linken ecke des umschließenden Quadrats
Ich vermute, dass in deinem Code
C#:
vecA = new Vector3(Prexe, Preye, 0);  //Sind Prexe und Preye die Koordinaten des pinken Punktes?
ist.
Zum Mittelpunkt gelangst du (wenn ich deinen Code richtig interpretiere) mittels:
C#:
vecB = new Vector3(radius, 0 ,0);  // Vektor mit Länge "Radius" erstellen, der parallel zur X-Achse zeigt
vecB.Roll(frames[j-1].AngleEnd +- 90);  // Vektor auf Winkel "im pinken Punkt" plus/minus 90° drehen
Die 90° musst du ggf. im Bogenmaß angeben, ich kenne die CodeProject-Klasse nicht. Das eine Vorzeichen ist für eine Linkskurve, das andere für eine Rechtskurve (welches welches ist musst du wissen)
Jetzt musst du nur noch vom Kreismittelpunkt zur linken oberen Ecke gehen:
C#:
vecC = new Vector3(+-radius, +-radius, 0);  // Vektor mit Länge "sqrt(2)*Radius" erstellen, der vom Kreismittelpunkt zur linken oberen Ecke des umschließenden Quadrats zeigt
Die richtigen Vorzeichen in vecC hängen wieder von der Wahl deines Koordinatensystems ab. Wenn die positive X-Achse nach rechts und die positive Y-Achse nach unten geht, dann musst du jeweils ein Minus wählen.
Den gelben Punkt erreichst du dann per Addition dieser drei Vektoren:
C#:
GelberPunkt = vecA + vecB + vecC;
 
Zuletzt bearbeitet:

KarlPichler

Mitglied
Okay ich checks nicht ganz.
Also der gelbe Punkt wird bereits errechnet!
Hab nur probier den x und y Kordinate etwas zu verschieben!
Den wirklichen Mittelpunkt des Kreises berechne ich auch! --> dank deiner Hilfe ;)

Allerdings geht der DrawArc immer vom linken oberen Punkt weg? (also seine x und y Location) richtig?, und nicht vom Mittelpunkt des Kreises!

Jap Prexe und Prexy sind immer die Endkoordinaten des vorgehenden Segments!

Gibt es eine Klasse bzw. einen Befehl der mir den DrawArc aus der mitte zeichnet?

Also so: Links ist momentan, und rechts hätte ich gern!

d3.jpg
Dann wärs erheblich einfacher!

Danke und Lg
 

KarlPichler

Mitglied
Ich glaub das schrieb ich bereits im vorherigen beitrag!

Ich war auf der suche nach einem DrawArc ersatz, der eben von der mitte aus zeichnet^^

lg