![]() |
Rotiertes Rechteck skalieren (vergrößern)?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,
ich versuche mich momentan an der Transformation von Rechtecken. Bisher besteht meine Rechteck-Klasse aus 4 simplen Punkten und kann um einen beliebigen Punkt rotiert werden. Jetzt muss ich die Klasse noch um eine Möglichkeit zur Skalierung erweitern. Bei einem nicht rotierten Rechteck ist dies ja kein Problem, da funktioniert folgendes für eine Skalierung mit [P1] (linke obere Ecke) als Ursprung:
Delphi-Quellcode:
Sobald das Rechteck aber in irgendeiner Form rotiert ist, geht das ganz fürchterlich in die Hose. Warum das so ist, ist mir klar, aber leider stehe ich beim finden einer universellen Lösung grade ziemlich auf dem Schlauch.
function TVXTransformedRect.Scale(const Origin: TVXPoint; ScaleX,
ScaleY: Double): TVXTransformedRect; begin Result.P1 := TVXPoint.Create(P1.X, P1.Y); Result.P2 := TVXPoint.Create(Round(P1.X + P1.Distance(P2) * ScaleX), P2.Y); Result.P3 := TVXPoint.Create(Round(P4.X + P4.Distance(P3) * ScaleX), Round(P2.Y + P2.Distance(P3) * ScaleY)); Result.P4 := TVXPoint.Create(P4.X, Round(P1.Y + P1.Distance(P4) * ScaleY)); end; Im Anhang ist mein Originalrechteck schwarz, das rotierte Recheck blau und der Versuch nach dem Rotieren zu Skalieren rot. Kann mir hier jemand weiterhelfen? Was ich nicht geht, ist mir die Rotation irgendwo zu merken, da ein Rechteck auch mehrfach (um verschiedene Punkte) rotiert werden kann. Viele Grüße Zacherl |
AW: Rotiertes Rechteck skalieren (vergrößern)?
Beziehen sich die ScaleX- und ScaleY-Werte auf das Koordinatensystem oder auf die Kanten des Rechtecks (dann passen die Namen aber nicht). Im ungedrehten Rechteck wäre das ja identisch.
|
AW: Rotiertes Rechteck skalieren (vergrößern)?
Wenn Du die Punkte einer Figur zentral zum Punkt P1 skalieren willst, dann gilt (aus der Lameng):
Code:
Dabei soll 's' der Skalierfaktor sein.
P'.x := P1.x + (P.x - P1.x) * s;
P'.y := P1.y + (P.y - P1.y) * s; Du musst also immer beide Dimensionen gemeinsam transformieren. |
AW: Rotiertes Rechteck skalieren (vergrößern)?
Zitat:
|
AW: Rotiertes Rechteck skalieren (vergrößern)?
Zitat:
Was ein wenig erstaunt ist, dass in der Abbildung die beiden P4-Punkte nicht in einer Linie mit P1 liegen. Dies müsste eigentlich gegeben sein. Edit: Doch, ist klar, es werden ja Distanzen nicht nur zu P1 gebildet. |
AW: Rotiertes Rechteck skalieren (vergrößern)?
Ich glaube meine Herangehensweise war nicht die beste und ich sollte besser auf Transformationsmatrizen umsteigen. Weiß jemand zufällig, wie DirectX einen Vector anhand der Transformationsmatrix transformiert? Dann könnte ich das einfach nachbauen.
|
AW: Rotiertes Rechteck skalieren (vergrößern)?
Entschuldigt den Doppelpost. Habe etwas mit den DirectX Transformationsmatrizen rumgespielt und da sind 2 Funktionen bei, die genau das können, was ich benötige.
Mit ![]() ![]() Letztere Funktion schaffe ich wohl selbst zu implementieren, aber was D3DXMatrixTransformation2D hinter den Kulissen macht, ist mir nicht ganz klar. Wäre hier über jede Info dankbar :) |
AW: Rotiertes Rechteck skalieren (vergrößern)?
Googele mal nach Homogene/Affine Transformation, das ist die Theorie, die dahinter steckt. Beispiele: graphics.ucsd.edu/courses/cse167_f05/CSE167_03.ppt oder
![]() |
AW: Rotiertes Rechteck skalieren (vergrößern)?
Danke :thumb:
Habe Scaling, Transformation und ZRotation nun (auf den ersten Blick korrekt) nachbilden können:
Delphi-Quellcode:
function VXMatrixTranslation(const X, Y, Z: Single): TVXMatrix;
begin Result := VXMatrixIdentity; Result._41 := X; Result._42 := Y; Result._43 := Z; end; function VXMatrixScaling(const Center: PVXVector3; SX, SY, SZ: Single): TVXMatrix; var TX, TY, TZ: Single; begin // TODO: Z-Komponente auf Korrektheit prüfen Result := VXMatrixIdentity; if Assigned(Center) then begin if (SX < 1) then TX := ((1 - SX) * Center^.X) else TX := (- ((SX - 1) * Center^.X)); if (SY < 1) then TY := ((1 - SY) * Center^.Y) else TY := (- ((SY - 1) * Center^.Y)); if (SZ < 1) then TZ := ((1 - SZ) * Center^.Z) else TZ := (- ((SZ - 1) * Center^.Z)); Result := VXMatrixTranslation(TX, TY, TZ); end; if (SX < 0) then SX := 0; Result._11 := SX; if (SY < 0) then SY := 0; Result._22 := SY; if (SZ < 0) then SZ := 0; Result._33 := SZ; end; function VXMatrixRotationZ(const Center: PVXVector3; AngleRadians: Single): TVXMatrix; var SinTheta, CosTheta: Single; begin Result := VXMatrixIdentity; SinTheta := Sin(AngleRadians); CosTheta := Cos(AngleRadians); if Assigned(Center) then begin Result := VXMatrixTranslation( CosTheta * (-Center.X) - SinTheta * (-Center.Y) + Center.X, SinTheta * (-Center.X) + CosTheta * (-Center.Y) + Center.Y, 0); end; Result._11 := CosTheta; Result._12 := SinTheta; Result._21 := -SinTheta; Result._22 := CosTheta; end; |
AW: Rotiertes Rechteck skalieren (vergrößern)?
Zitat:
Wie man Winkel berechnet, findest du durch ![]() ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz