PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Punkt zwischen 4 Geraden ? (PB)



MagicMagor
13.02.2004, 04:37
Tja.. ich zerbrech mir hier den Kopf über ein kleines Problem und mir gehen die Ideen aus, woran es liegen könnte.

Folgendes Problem:
Ich möchte wissen ob sich der MausCursor innerhalb der von mir gezeichneten Map befindet. Die Map bildet eine Raute.
Der Ansatz ist, von den 4 Kanten der Map Geradenfunktionen zu bilden, den MausX-Wert einzusetzen und den MausY dann mit den Ergebnissen zu überprüfen.
Komischerweise ist einzig und allein der 1. Wert der Ausreißer der immer größer als MausY ist, obwohl er kleiner sein sollte..



Procedure IsPointeronMap(MausX, MausY)
xStart = Map(0,0)\xPos
yStart = Map(0,0)\yPos + (#Kachel_Hoehe/2)
bG0.f = yStart - (#Kachel_Steigung*xStart)
bGX.f = bG0 + (MapSizeY*#Kachel_Hoehe)
yG0.f = #Kachel_Steigung*MausX + bG0
yGX.f = #Kachel_Steigung*MausX + bGX

bF0.f = yStart + (#Kachel_Steigung*xStart)
bFX.f = bF0 - (MapSizeY*#Kachel_Hoehe)
yF0.f = -#Kachel_Steigung*MausX + bF0
yFX.f = -#Kachel_Steigung*MausX + bFX

result = 0
If MausY > yG0 And MausY < yGX And MausY < yF0 And MausY > yFX
result = 1
EndIf

ProcedureReturn result
EndProcedure

Ich kann leider keine Skizze liefern.. aber ich hoffe ihr könnt den obigen Code nachvollziehen... Wie gesagt ist immer der Wert yG0 größer als MausY, auch wenn er nach der Logik her kleiner sein müßte. Ich erkenne aber keinen Fehler in meiner Berechnung...
Ich hoffe ihr könnt mir helfen..

PS: Falls etwas unklar ist, sagen und ich liefer Infos nach.

PPS: xStart und yStart sind die Pixelkoordinaten des linken Eckpunktes der Raute..

Edit: Problem ist gelöst.. in Ruhe nachdenken hilft (Vorzeichen an einigen Stellen falsch *vorKopfschlag*)

Ineluki
13.02.2004, 23:34
auch wenn du das problem schon geloest hast ... irgendwie sieht mir das recht kompliziert aus ^^

Ich hab mich mal ran gemacht und das ganze ueber eine Koordinatentransformation mit 2D Vektoren geloest ...

Eine Raute wird ja ueber zwei Vektoren aufgespannt, ausgehend vom gleichen Startpunkt SS ... nennen wir sie E und F

Wenn ich nun wissen will, ob der Mauspunkt (x,y) in der raute liegt, ist das einzige, was ich tun muss, die Mousekoordinaten in Koordinaten des Koordinatensystems, das durch E,F aufgespannt wird umwandeln (natuerlich muss das nicht rechtwinklig sein, sind also keine karthesischen koordinaten)

Da der Maximal moegliche Punkt, der noch in der Raute liegt genau durch E+F gebildet wird (also der Punkt, der dem Ursprung gegenueber liegt) und der in den reformierten koordinaten natuerlich den Punkt (1,1) ausmacht, koennen wir einfach sagen, wenn die reformierten Mauskoordinaten fuer x und y zwischen 0 und 1 liegen, ist der Punkt in der Raute ....

Noch ein kurzer Kommentar zu meiner Nomenklatur ...
* Punkte mit zwei Grossbuchstaben sind in globalen kartesischen Koordinaten (also im allgemeinen Pixelkoordinaten)
* Punkte mit einem Grossbuchstaben sind relativ zum neuen Ursprung SS
* Die zwei Komponenten eines Punktes haben die Indices x bzw y
* a,b sind die Koordinaten im nicht kartesischen Koordinatensystem, aufgespannt durch E,F mit Ursprung SS

so ... nun zur Rechnung ...
Die Raute wird durch die Punkte SS, PE und PF aufgespannt. Die Maus ist im Punkt PM. zuerst ueberfuehren wir die Koordinaten so, dass SS im Ursprung liegt durch eine einfache Translation.


Ex=PEx-SSx; Ey=PEy-SSy; // der eine Vektor der die Raute aufspannt
Fx=PFx-SSx; Fy=PFy-SSy; // der zweite Vektor, der die Raute aufspannt
Mx=PMx-SSx; My=PMy-SSy; // die Mausposition relativ zu SS

Nun rechnen wir die Mauskoordinaten ins Koordinatensystem E,F um


a=(Mx*Fy-My*Fx)/(Ex*Fy-Ey*Fx); // Neue Mausposition entlang E
b=(My*Ex-Mx*Ey)/(Ex*Fy-Ey*Fx); // Neue Mausposition entlang F

Und nun die einfache Ueberpruefung ..


If a>=0 and a<=1 and b>=0 and b<=1 then .... // Maus ist in der Raute

hoffe, du kannst damit was Anfangen .... zur Not geb ich dir auch die Herleitung der Formeln ^_____^

So ists zumindest um einiges Uebersichtlicher ... eventuell kannst du dir in deinem konkreten Fall sogar viele Berechnungen Sparen, da du ja nur eine Map hast und deren Vektoren (relativ zum Ursprung) ja kennst.

Das ganze ist nicht nur viel uebersichtlicher als die Geradenvariante, sondern bietet auch noch ein paar Vorteile ...

A) Es ist egal, wie die Punkte SS,PE und PF liegen, die Raute wird immer korrekt aufgespannt.
Es gilt immer: M = a*E + b*F bzw PM = a*E + b*F + SS ... daran aendert sich auch nichts, wenn die Vektoren z.B. negative Komponenten enthalten (z.B. wenn du das Koordinatensystem von rechts nach links laufen laesst), dann sind a und b trotzdem noch positiv, wenn die Maus in der Raute liegt.

B) Solltest du deine Map mit vielen kleinen Rauten aufbauen (wie es bei isometrischer Ansicht ja meist der Fall ist) brauchst du als Raute nicht die Ganze Map angeben, sondern nur eine der kleinen Rauten. Dann bekommst du durch die umgerechneten Mauskoordinaten sofort raus, in welcher Raute sich die Maus befinet, indem du einfach die Nachkommastellen abschneidest ... und dann erhaellst du Beispielsweise dritte Raute nach rechts und zweite raute nach oben als Ergebnis (was sich sehr gut macht, wenn du die Rauten in einem 2D Array verwaltest). Dann musst du natuerlich nicht auf <=1 sondern auf <=MaxAnzahlAnRautenProAchse testen

Hoffe, das dir das vielleicht etwas weiter hilft

Gruss Ineluki

MagicMagor
26.02.2004, 21:37
So nochmal etwas genauer über deinen Ansatz nachgedacht.


Nun rechnen wir die Mauskoordinaten ins Koordinatensystem E,F um

code:
a=(Mx*Fy-My*Fx)/(Ex*Fy-Ey*Fx); // Neue Mausposition entlang E
b=(My*Ex-Mx*Ey)/(Ex*Fy-Ey*Fx); // Neue Mausposition entlang F

Diese Umrechnung ist mir nicht ganz klar. Es ist logisch, daß durch 2 Vektoren ein Koordinatensystem aufgespannt wird, aber wie kommst du zu dieser Umrechnung? Wie ich schon im Chat gesagt, sind meine Kentnisse der Vektorgeometrie nicht mehr ganz frisch..
Ich glaub der Rest ist mir ziemlich einleuchtend..

Onii-chan
26.02.2004, 22:24
Das ganze funktioniert über Transformation von Koordinatensystemen. Du kannst mit zwei nicht parallelen Geraden ein zweidimensionales Koordinatensystem bilden und für einen Punkt bestimmen, in welchem Quadranten er liegt. Ist ziemlich lange her, daß ich mich mit sowas befasst habe, aber ne Mathematische Formelsammlung hilft dir da sicher enorm weiter ;)

Ich versuch mal einen Theoretischen Ansatz für ein n-seitiges Polygon aus dem Ärmel zu schütteln, daß mach ich aber in einem eigenen Thread. ;)

MagicMagor
26.02.2004, 22:36
aber ne Mathematische Formelsammlung hilft dir da sicher enorm weiter
So eine habe ich, allerdings in Düsseldorf, wo ich erst nächste Woche wieder hinfahre. *g*

Aber Ineluki hat es mir im Chat ausführlich erklärt. Hab vorher niemals mit Transformation von Koordinatensystem zu tun gehabt.
Aber jetzt hab ichs verstanden. *g*

Ineluki
26.02.2004, 22:38
Wir haben ja folgendes definiert

Allgemeiner Punkt in kartesischen Koordinaten :

(p,q) = p*X + q*Y

die Vektoren, die das Parallelogramm aufspannen:

E = ex*X + ey*Y
F = fx*X + fy*Y

der allgemeine Punkt im relativen Koordinatensystem

[a,b] = a*E + b*F

Daraus folgt:
die Definition von E,F in [a,b] eingesetzt

[a,b] = a*(ex*X + ey*Y) + b*(fx*X + fy*Y)

separiert nach x und Y

[a,b] = (a*ex + b*fx)*X + (a*ey + b*fy)*Y

ist nach definition von (p,q) und eingesetzt

p = a*ex + b*fx
q = b*ey + b*fy

ein Gleichungssystem aus zwei Gleichungen und zwei Unbekannten, da p,q die Mausskoordinaten sind und ex,ey,fx,fy die vorgegebenen Komponenten der Vektoren. Umgestellt nach a,b ergibt sich obige Gleichung.

Gruss Ineluki