Winkelfunktionen - Richtungspfeile am Rand

  • Moin moin,

    Mir fällt leider keine direkte Überschrift dazu ein, ich versuchs euch aber mal zu erklären.

    Ich habe ein Quadrat und die Mitte des Quadrads gibt die Position des Spielers an. Das Quadrad ist unterteilt in mehrere kleinere Quadrate (Felder). Spieler die sich außerhalb der Sichtweite befinden würde ich gerne Kennzeichnen und mit einem Richtungspfeil anzeigen lassen.

    Was ich besitze: Den Winkel zum Spieler hin, die Pixellänge in 180* bzw 90* sagen wir einfach mal 200px. Das Problem jedoch ist, zeichne ich jetzt den Pfeil und der spieler hat einen Winkel von 135 (Diagonal linksoben) Dann würde der Pfeil miten im Quadrad iegen und nicht in der Ecke wo es hin soll.

    Jedes Feld im "großen Quadrat" ist 20x20px

    Hättet ihr ne möglichkeit dies zu lösen?

  • Mir fiele das ein:

    Idee:
    a) Wenn du die Endpunkte jeder Seite mit dem Mittelpunkt verbindest ist der Winkel zwischen diesen Linien immer 90°.
    b) Ergo kann jedem Winkel eindeutig ein Punkt auf der Außenseite zugewiesen werden.

    Algo:
    1) Du dividierst durch 360.0. Dadurch hast du nun einen Wert von 0-1 (in den meisten Fällen mit 'ner Menge Nachkommastellen).
    1a) Vorraussetzung ist, dass dein Winkel immer im Wertbereich [0; 360] ist.

    2) Du multiplizierst das Ergebnis mit 4.0. Den neuen Wert nennen wir mal Index. (die Nachkommastellen sind immer noch wichtig)

    3) Jetzt erstellst du ein Array mit 6 Einträgen:
    [0]: Position vom 1. Endpunkt.
    [1]: Position vom 2. Endpunkt.
    [2]: Position vom 3. Endpunkt.
    [3]: Position vom 4. Endpunkt.
    [4]: Position vom 1. Endpunkt.
    [5]: Position vom 2. Endpunkt. (Wird gebraucht wenn Index gleich 4 ist. Genau genommen kann da auch 0 drinnen stehen. Es muss halt derselbe Typ wie die anderen Einträge sein)

    4) Du teilst "Index" auf
    -> Ganzzahlanteil kommt in die Variable idx
    -> Nachkommaanteil in die Variable factor.

    5) Du interpolierst linear zwischen den Einträgen "idx" und "idx + 1" (aus dem Array) mit dem Faktor "factor".

    6) Das Ergebnis der Interpolation ist deine gesuchte Postion am Rand des Quadrats.
    7) Fertig.

    Lineare Interpolation:

    AutoIt
    ;$a = erster Wert (wird return'ed wenn $s = 0)
    ;$b = zweiter Wert (wird return'ed wenn $s = 1)
    ;$s = Interpolationsfaktor (0-1)
    Func lerp($a, $b, $s)
         Return( $a + (($b - $a) * $s) )
    EndFunc

    4 Mal editiert, zuletzt von CentuCore (25. März 2016 um 09:20)

  • Ich bin mir nicht ganz sicher, ob ich begriffen habe, um was es eigentlich geht?!
    Das wird am X-Y-Problem liegen...wie so oft || (siehe Link in meiner Signatur)

    WO IST DAS PROBLEM? Den Pfeil zu zeichnen, die Richtung zu ermitteln, die Position der Linie zu zeichnen uswusf. ?
    Wenn dein Richtungsanzeiger bis zum Rand des äußeren Quadrates reichen soll, wieso nutzt du nicht einfach nur das Dreieck, dessen Winkel bekannt ist und dessen Kathethe/Gegenkathete IMMER der Radius des Kreises ist?
    Du musst auch nur den Winkel 0 bis 45° betrachten, alle anderen "Richtungsanzeiger" lassen sich durch Spiegeln an der X- und Y-Achse ermitteln.
    Für a=30° und R=200 werden die Koordinaten auf dem äußeren Quadrat gesucht, dabei ist die X-Koordinate bekannt, nämlich R:
    tan(a)= Y / R
    0,577 * 200 = Y
    115 = Y

    Für 180-a ist Y=115
    Für 180+a ist Y=-115
    Für 360-a ist Y=-115

    Jetzt die Frage an die Geometriker...wie sind X und Y bei 90-a, 90+a, 270-a und 270+a....*hust* wer dafür einen Taschenrechner braucht, der sollte besser sein Talent in anderen Bereichen ausbauen :Face:

  • Damit würde ich die Diagonale bekommen die bis in die Ecke geht, fehlt nurnoch der Raum dazwischen den man mit PI im laufschritt verkleinern könnte jenachdem welchen winkel man hat?

    Nein, ließ dir meinen Algo durch.
    Mit der Interpolation kriegst du auch die Zwischenpunkte je nachdem welchen Winkel du eingibst.

    Wenn du was anderes wolltest beschreib bitte was du möchtest.
    Das fehlt mir irgendwie.

  • Nicht falsch verstehen, ich schau mir deinen Beitrag später in Ruhe an, wollte aber noch was beifügen das mir noch eingefallen ist. Bin noch auf der Arbeit, ;)

    Andy: Der Richtungszeiger soll nur am Ende als kleines Symbol dargestellt werden, jenachdem wie der Winkel zum Anderen Spieler ist. Er soll nicht auf dem Radius liegen sondern an den Kanten des Quadrats.

  • Er soll nicht auf dem Radius liegen sondern an den Kanten des Quadrats.

    Ja, das habe ich kapiert
    Wie du an die Koordinaten auf der Quadratkante kommst, habe ich dir ja gezeigt. Und die "Pfeillänge" ist ja auch kein Problem. Der Endpunkt ist bekannt und die Pfeillänge wird durch die Koordinate beschrieben, die der Schnittpunkt eines Kreises mit kleinerem Radius und der "Pfeillinie" ergibt.
    Kreisfunktion x²+y²=r² und Geradengleichung y=m*x+b mit Steigung m = (y2-y1)/(x2-x1)

  • So habe ich mir das vorgestellt...


    Man kann natürlich massiv zusammenfassen, um auch die Ausführungsgeschwindigkeit zu erhöhen (darauf kommts bei Spielen meistens an).
    Letztendlich bleibt pro Pfeil 1x der Tangens zu berechnen und bissl Bitgeschiebe durch OR und die Multiplikation/Division...
    Wenn in einer (Compiler-) Hochsprache der Tangens zu lange dauert (FPTAN Latency ca. 250-300 Takte, Throughput ca. 170 Takte) legt man sich eine LookUpTabelle mit den Tangenswerten von 0-359° in ein Array und greift über den Index zu (maximal 5-10 Takte aus dem Speicher / Prozessorcache)

    Nach einigen Optimierungen und Vereinfachungen sieht das doch schon ganz schön schnell aus.
    Jetzt werden auch nur 4 Quadranten benutzt...

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    7 Mal editiert, zuletzt von Andy (25. März 2016 um 23:21)

  • Hi,
    ich vermute mal, so soll es letztendlich funktionieren. Mausposition abfragen und den Pfeil zeichnen.
    Das Puffergedöns um den Pfeil wieder zu "löschen" und die Abfrage, ob die Mausposition innerhalb des Fensters ist, überlasse ich mal dem TE.