Sooo ich habe meinen Fehler gefunden (wie gesagt neu und so),
deine verlinkten Artikel haben mich erstmal darauf gebracht, dass sich Canvas.GetLeft() usw. gar nicht mit der Drehung ändert. Ich hatte anfangs gedacht, der Punkt würde sich entsprechend mit drehen. Wir fangen ja alle mal an xD
Die Formel in dem Artikel konnte mir allerdings auch nicht weiterhelfen, weshalb ich mal meine Mathefähigkeiten aus der neunten Klasse ausgepackt habe und mir mit rechtwinkligen Dreiecken eine Formel (bzw. um nicht so viele Abschreibfehler einzubauen mehrere Formeln) zusammengebaut hab:
public void DrawLineAbove(string rec_name)
{
Rectangle rectangle = testCanvas.FindName(rec_name) as Rectangle;
double rec_width = rectangle.Width;
double rec_height = rectangle.Height;
double rec_left=Canvas.GetLeft(rectangle);
double rec_top =Canvas.GetTop(rectangle);
double rA = 0;
if (rectangle.RenderTransform is TransformGroup transformGroup)
{
foreach (var transform in transformGroup.Children)
{
if (transform is RotateTransform rotateTransform)
{
rA = rotateTransform.Angle * (Math.PI / 180.0);
break;
}
}
}
double r = Math.Sqrt(Math.Pow(rec_height/2,2)+ Math.Pow(rec_width / 2, 2));
double s = 2 * r * Math.Sin(rA / 2);
double gamma = Math.Atan(rec_height / rec_width);
double beta = (Math.PI - rA) / 2;
double delta = Math.PI/2-(beta-gamma);
double dx = Math.Sin(delta)*s;
double dy = Math.Cos(delta)*s;
double x2 = rec_left + dx + (Math.Cos(rA) * rec_width);
double y2 = rec_top - dy + (Math.Sin(rA) * rec_width);
Line line = new Line();
line.X1 =rec_left + dx;
line.Y1 =rec_top - dy;
line.X2 = x2;
line.Y2 = y2;
line.StrokeThickness = 3;
line.Stroke = Brushes.Blue;
testCanvas.Children.Add(line);
Jetzt muss ich nur noch den Abstand berücksichtigen, das stellt aber nunmehr weniger ein Problem dar, da ich die Berechnung dafür ja schon habe.
Vielen Dank für die Hilfe 😃
Zitat von Th69
Mathematisch erscheint mir deine Formel aber fehlerhaft, denn ein Abstand sollte ja eine Addition sein, keine Multiplikation.
Richtige Rotationsformel s. Drehmatrix der Ebene ℝ² und Transformationen in 2D mit Matrizen.
Und eine Rotation berechnet sich üblicherweise aus: -Translation → Rotation → +Translation (wobei Translation zum Rotationsmittelpunkt gemeint ist).
Auf englisch habe ich dazu auch Revised Right End Point of rotated rectangle in C# gefunden (beachte besonders die Berechnung des
Radius
in der 1. Lösung, d.h. den Abstand des Eckpunktes zum Mittelpunkt).
Guten Morgen 😃,
Ziel soll es sein, dass sich über aneinander gereihte Rechtecke, ein Rahmen bildet, wenn eine bestimmte Bedingung erfüllt ist. Da das für jeden Weg möglich sein soll, soll die Linie durch Code und nicht schon vorher durch mich gezeichnet werden. Beispiel siehe Anhang (gerade rüber ist nicht das Problem, von Rechteck 11 nach Rechteck 03 über 13 wird spannender)
Um das Ganze auszuprobieren soll erstmal pro Rechteck eine Linie darüber gezeichnet werden, so wie im Problem beschrieben. Über das Verbinden mache ich mir später Gedanken.
Die Rechtecke habe ich in XAML gesetzt.
Mathematisch sollte alles hinhauen. Da die berechneten Punkte der Linie gleich dem des Rechtecks sind, wenn der Abstand auf 0 gesetzt wird. Trotzdem wird bei Rotationswinkeln > 0 Grad (ich nehme an um den Mittelpunkt) die Linie nach unten links verschoben wird.
Wenn ihr eine Idee habt, wie ich das oben beschriebene Problem besser lösen kann, bin ich dafür auch gerne offen 😃
Hallo liebe Community,
ich bin noch ziemlich neu, deswegen habt bitte etwas Nachsicht.
Ich habe ein Rechteck in einem Canvas ("L_LBL") platziert und würde gerne eine Linie 5px oberhalb der oberen Seite des Rechtecks einfügen. Dabei soll es egal sein, ob das Rechteck gedreht ist oder nicht. Nachdem ich das ganze mathematisch angegangen bin, kam ich zu folgendem Code:
public void DrawLineAbove(string rec_name)
{
Rectangle rectangle = L_LBL.FindName(rec_name) as Rectangle;
double rec_width = rectangle.Width;
double rotationAngle = 0;
int abstand = 0;
if (rectangle.RenderTransform is TransformGroup transformGroup)
{
foreach (var transform in transformGroup.Children)
{
if (transform is RotateTransform rotateTransform)
{
rotationAngle = rotateTransform.Angle * (Math.PI / 180.0);
Console.WriteLine("Rotationswinkel des Rechtecks: " + rotationAngle);
break;
}
}
}
double xU = Canvas.GetLeft(rectangle);
double yU = Canvas.GetTop(rectangle);
double x1 = xU + (Math.Sin(rotationAngle) * abstand);
double y1 = yU - (Math.Cos(rotationAngle) * abstand);
double x2 = x1 + (Math.Cos(rotationAngle) * rec_width);
double y2 = y1 + (Math.Sin(rotationAngle) * rec_width);
Line line = new Line();
line.Stroke = Brushes.Blue;
line.StrokeThickness = 3;
line.X1 = x1;
line.Y1 = y1;
line.X2 = x2;
line.Y2= y2;
L_LBL.Children.Add(line);
//Console.WriteLine(rec_width);
//Console.WriteLine(xU);
//Console.WriteLine(yU);
//Console.WriteLine(x1);
//Console.WriteLine(y1);
//Console.WriteLine(x2);
//Console.WriteLine(y2);
Console.WriteLine(Canvas.GetTop(line));
Console.WriteLine(Canvas.GetLeft(line));
Console.WriteLine(Canvas.GetTop(rectangle));
Console.WriteLine(Canvas.GetLeft(rectangle));
}
Probehalber habe ich den Abstand mal auf null gesetzt. Bedeutet, die Punkte des Rechteckes und die der Linie müssten übereinstimmen. Das ist auch so. Beträgt der Rotationswinkel 0° funktioniert alles super und die Linie legt sich genau auf die Seite des Rechteckes. Ist der Rotationswinkel allerdings > 0° verschiebt sich die Linie nach links unten, obwohl sie genau die gleichen Punkte hat wie das Rechteck.
Console.WriteLine(Canvas.GetTop(line));
Console.WriteLine(Canvas.GetLeft(line));
...ergaben jeweils "NaN".
Ich weiß leider nicht weiter und bin auf eure Expertise angewiesen. Die Berechnung stimmt, nur beim Zeichnen der Linie, wenn der Rotationswinkel > 0° ist, wird's doof.
Ich danke euch schonmal in Voraus 😃
LG Dominik