Zurück   Flashforum > Flash > ActionScript > ActionScript 1

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 14-05-2004, 13:40   #1 (permalink)
Farbe ist Luxus
 
Benutzerbild von ludabruda
 
Registriert seit: May 2003
Ort: Köln
Beiträge: 2.405
Kreisberechnung Isometrie

Hallo Iso-Häuptlinge

Ich habe ein Problem bei der Berechnung von Winkeln und Längen in einem Kreis in der Isometrie.

Mein Kreis hat zunächst einen Durchmesser von sagen wir 100 Pixeln. Für die isometrische Darstellung vergrößere ich die Breite des Kreises mit Math.cos(30*Math.PI/180)*2, also dem Faktor 1.73.

Ich möchte nun vom Zentrum des Kreises eine Linie in Richtung der Maus zeichnen. Diese soll aber nicht über den Umriss des Kreises hinausgehen. Also, wenn die Maus innerhalb des Kreises ist, bis zur Maus, wenn außerhalb, bis zum Rand des Kreises.

Ich berechne hierzu zunächst die Distanz von Maus-Kreis mit dem Pythagoras und ermittle den Winkel zwischen Maus und Kreis mittels Math.atan2(_root._ymouse-kreis._y,_root._xmouse-kreis._x);

Bei richtigem Winkel der Linie ist diese allerdings entweder zu lang oder zu kurz, übertritt also entweder den Kreis oder erreicht die Outline nicht.
Füge ich den Faktor von 1.73 auch hier wieder ein, ist die Linie perfekt auf dem Kreis, allerdings weicht der Winkel vom eigentlichen Winkel ab, da ich den Faktor nur auf den X-Wert draufschlage

In der angehängten fla könnt ihr sehen, was ich meine.

In anderen Isometrie-Threads wird die Isometrie oft mit Drehung um 45° und halbieren der Höhe erreicht. Ist das nur eine vereinfachte Annäherung oder gibt es einen anderen Grund, das so zu tun? Bin ich vielleicht mit meinem Ansatz auf dem Holzweg?

Ich würde mich freuen, wenn ihr euch meines Problems annehmen könntet...

Grüße
Sascha
Angehängte Dateien
Dateityp: rar iso_kreis_winkel.rar (1,9 KB, 34x aufgerufen)
__________________
12:15, press return
ludabruda ist offline   Mit Zitat antworten
Alt 14-05-2004, 17:12   #2 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
Ich versuche einfach mal eine Lösung herzuleiten.

Ich nehme an, dass die Ellipse dadurch entsteht, dass man einen Kreis mit dem Radius r um den Faktor k streckt,
indem man die X-Koordinate jedes Punktes auf dem Kreis mit k multipliziert, und dort seinen neuen Punkt malt.

Wenn auf dem Kreis gilt:

x^2 + y^2 = r^2

dann gilt nun für die neuen Punkte

(x / k)^2 + y^2 = r^2

Desweiteren gilt für alle Punkte, die zwischen deinem Vorgabepunkt (der Maus in diesem Fall) und dem Mittelpunkt des Kreises liegen:

y / x = tan(alpha)

wobei alpha der Winkel des Vorgabepunktes ist.
Das sieht schon ganz gut aus, wir haben die zwei Variablen x und y, und zwei Gleichungen.

Diese letzte Gleichung lässt sich nun jeweils nach x und nach y auflösen:

y = x * tan(alpha)
x = y / tan(alpha)

Wenn man diese beiden Gleichungen nun in die Gleichung unserer Ellipsenpunkte einsetzen, erhält man:

x^2 / k^2 + x^2 * tan^2(alpha) = r^2

und

y^2 / k^2 / tan^2(alpha) + y^2 = r^2

Wenn man nun auf der linken Seite der jeweiligen Gleichung x, bzw. y ausklammert, und den Rest auf die andere Seite bringt, erhält man:

x^2 = r^2 / (1 / k^2 + tan^2(alpha))

und

y^2 = r^2 / (1 / (k^2 * tan^2(alpha) + 1))

jetzt wird es unschön, denn wir müssen die Wurzel ziehen.
Schön das es immerhin möglich ist, r ist positiv, k^2 ist immer positiv, tan^2 auch, also ist alles positiv.

Es ergibt sich also:

x = r / sqrt(1 / k^2 + tan^2(alpha))

und

y = r / sqrt(1 / (k^2 * tan^2(alpha) + 1))


Dies sind nun die Koordinaten relativ zum Mittelpunkt der Ellipse.
Wie man sieht, fehlt uns noch der tan(alpha), aber der ist bekanntlich nichts andres als y / x, allerdings relativ zum Mittelpunkt, also in Flash:

dx = _xmouse - mittelpunktX;
dy = _ymouse - mittelpunktY;

tanalpha = dy / dx;

Leider fehlen uns die Vorzeichen, will meinen, wir haben nur den Betrag der Koordinaten.

Dieses Problem lösen wir in Flash aber einfach, indem wir die richtigen Richtungen getrennt ermitteln, z.B. so:

richtungX = (dx < 0)?(-1):(1);
richtungY = (dy < 0)?(-1):(1);

dann muss man die Koordinaten nur noch absolut umrechnen, und fertig:

absolutesX = mittelpunktX + x * richtungX;
absolutesY = mittelpunktY + y * richtungY;


Um nun dieses Ergebnis zu verwenden, prüfst du erstmal, ob die Maus in der Ellipse liegt:

ActionScript:
  1. radiusAufEllipse = Math.sqrt(absolutesX * absolutesX + absolutesY * absolutesY);
  2.  
  3. if(radiusAufEllipse < mausRadius)
  4. {
  5.     // nichts machen, alles ok, die Maus ist weit weg
  6. }
  7. else
  8. {
  9.     absolutesX = absolutesX / radiusAufEllipse * mausRadius;
  10.     absolutesY = absolutesy / radiusAufEllipse * mausRadius;
  11. }

So, ich glaube das wars, die Formeln oben musste dir eben noch in AS umschreiben, da bin ich jetzt zu faul...

EDIT: Welcher Held hat das eigentlich mit den smillies erfunden?
EDIT2: bekanntlich ist tan = x / y... wers glaubt :)

Geändert von Janoscharlipp (14-05-2004 um 17:53 Uhr)
Janoscharlipp ist offline   Mit Zitat antworten
Alt 14-05-2004, 17:34   #3 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
Zitat:
Geschrieben von Janoscharlipp

ActionScript:
  1. radiusAufEllipse = Math.sqrt(absolutesX * absolutesX + absolutesY * absolutesY);
  2.  
  3. if(radiusAufEllipse < mausRadius)
  4. {
  5.     // nichts machen, alles ok, die Maus ist weit weg
  6. }
  7. else
  8. {
  9.     absolutesX = absolutesX / radiusAufEllipse * mausRadius;
  10.     absolutesY = absolutesy / radiusAufEllipse * mausRadius;
  11. }
vergiss das, ich war in so nem Lauf, da habe ich nicht gemerkt, dass dem Fall, in dem die Maus innerhalb der Ellipse liegt, der gesuchte Punkt die Maus selbst ist...

Also hier mein Script:
ActionScript:
  1. _root.C = {x: 400, y: 200}; // der Mittelpunkt
  2. _root.r = 100; // der Radius des Kreises
  3. _root.k = 2; // der Streckungsfaktor
  4.  
  5. _root.onEnterFrame = function()
  6. {
  7.     var dx = _xmouse - C.x;
  8.     var dy = _ymouse - C.y;
  9.    
  10.     var tana = dy / dx;
  11.    
  12.     var x = r / Math.sqrt(1 / (k * k) + tana * tana);
  13.     var y = r / Math.sqrt(1 / (k * k * tana * tana) + 1);
  14.    
  15.     var radiusAufEllipseQuadrat = x * x + y * y;
  16.    
  17.     var mausRadiusQuadrat = dx * dx + dy * dy;
  18.  
  19.     if(radiusAufEllipseQuadrat > mausRadiusQuadrat)
  20.     {
  21.         // sozusagen alles umsonst, der Punkt ist die Maus
  22.         x = dx;
  23.         y = dy;
  24.     }
  25.     else
  26.     {
  27.         // wird benötigt, nur noch die Richtungen berechnen
  28.         x *= (dx < 0)?(-1):(1);
  29.         y *= (dy < 0)?(-1):(1);
  30.     }
  31.    
  32.     _root.clear();
  33.     _root.lineStyle(1);
  34.     _root.moveTo(C.x, C.y);
  35.     _root.lineTo(C.x + x, C.y + y);
  36. }

und im Anhang das .fla dazu.

EDIT: schon wieder die Gelbköpfe...
Angehängte Dateien
Dateityp: zip ellipse.zip (2,7 KB, 76x aufgerufen)

Geändert von Janoscharlipp (14-05-2004 um 17:35 Uhr)
Janoscharlipp ist offline   Mit Zitat antworten
Alt 18-05-2004, 08:28   #4 (permalink)
Farbe ist Luxus
 
Benutzerbild von ludabruda
 
Registriert seit: May 2003
Ort: Köln
Beiträge: 2.405
Hi Janoscharlipp,

wow, vielen Dank, ich bin begeistert.
Ich hatte den Umweg versucht, aus den Iso-Koordinaten den Winkel in der Isometrie zu berechnen. Das gelingt zwar auch, aber es nützt eben nix. Die Differenz sah man ja in meinem Beispiel. Ich hatte mich die ganze Zeit an der Drehung um 30° in der Isometrie festgehalten. Auf die Idee, dass es sich ja schließlich um eine Ellipse handelt, war ich gar nicht gekommen... Manchmal stehe ich voll auf dem Schlauch.

Sag mal, ist es eigentlich Zufall, dass 2*sin(45°) bzw. 2*cos(45°) gleich sqrt(2) ist? Gibt es da einen Zusammenhang, den ich nicht sehe? Oder stelle ich da einen Zusammenhang her, der gar nicht existiert....?

Grüße
Sascha
__________________
12:15, press return
ludabruda ist offline   Mit Zitat antworten
Alt 18-05-2004, 18:35   #5 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
ja, da gibt es einen Zusammenhang.

In der Schule werden Sinus und Cosinus als Ordinaten (y-Achse) bzw. Abszisse eines Punktes mit Winkel alpha auf dem Einheitskreis eingeführt.

Dabei ist 0° bei 3 Uhr, und die Richtung ist entgegend dem Uhrzeigersinn.
Wenn du dir nun 45 Grad vorstellst, läge der Punkt genau auf der Diagonalen durch den Ursprung nach rechts oben.
Dann ist die Ordinate genau gleich der Abszisse (ein Kästchen nach rechts, eins nach oben ) (wenn du sehr komische Kästchen hast )

Da ja immer ein rechter Winkel da ist, muss immer gelten: (nach Pythagoras; oder wie man den schreibt)
x^2 + y^2 = r^2

in unserem Spezialfall 45° ist aber x = y, also auch
2 x^2 = r^2, also x = 1 / 2 sqrt(r)

und auf dem Einheitskreis also
x = y = 1 / 2 sqrt(2)

ich weiß, ganz wirre Erklärung, hoffe es ist trotzdem zu verstehen.
Janoscharlipp ist offline   Mit Zitat antworten
Alt 18-05-2004, 18:43   #6 (permalink)
Farbe ist Luxus
 
Benutzerbild von ludabruda
 
Registriert seit: May 2003
Ort: Köln
Beiträge: 2.405
Hi,

ja, natürlich, die Diagonale eines Quadrats mit Seitenlänge 1 ist nunmal sqrt(2)...

Schön, sich ab und zu mal wieder den Mittelstufenwind durch die Synapsen wehen zu lassen

Nochmals Danke...

Grüße
Sascha
__________________
12:15, press return
ludabruda ist offline   Mit Zitat antworten
Alt 18-05-2004, 19:02   #7 (permalink)
muh
 
Benutzerbild von Janoscharlipp
 
Registriert seit: Apr 2002
Ort: Freiburg / Stuttgart
Beiträge: 4.338
ahh, genau das meinte ich doch

mir sitzt das ganze noch ziemlich tief...da bläst der Wind aus der anderen Richtung.
Janoscharlipp ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an



Alle Zeitangaben in WEZ +1. Es ist jetzt 20:46 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele