Struggeling übersetzt die Position der Maus an die Position der Kacheln in meinem Raster. Wenn alles flach ist, sieht die Mathematik so aus:
%Vor% wobei pos.x
und pos.y
die Position der Maus, 240 und 320 der Offset, 24 und 48 die Größe der Kachel sind. Position enthält dann die Gitterkoordinate der Kachel, über der ich schwebe. Dies funktioniert einigermaßen gut auf einer ebenen Oberfläche.
Jetzt füge ich Höhe hinzu, die die Mathematik nicht berücksichtigt.
Dieses Raster ist ein 2D-Raster mit Rauschen, das in Höhe und Kacheltyp übersetzt wird. Die Höhe ist wirklich nur eine Anpassung an die 'Y'-Position des Plättchens, daher können zwei Plättchen an derselben Stelle gezeichnet werden.
Ich weiß nicht, wie ich feststellen soll, auf welcher Kachel ich schwebe.
bearbeiten:
Ich habe Fortschritte gemacht ... Vorher war ich auf das mouseover-Ereignis angewiesen, um die Gitterposition zu berechnen. Ich habe das einfach geändert, um die Berechnung in der Zeichenschleife selbst durchzuführen und zu überprüfen, ob die Koordinaten innerhalb der Grenzen der gerade gezeichneten Kachel liegen. schafft einige overhead tho, nicht sicher, ob ich super glücklich bin, aber ich werde bestätigen, ob es funktioniert.
2018 bearbeiten:
Ich habe keine Antwort, aber da dies ein offenes Kopfgeld ist, helft euch selbst Code und eine Demo
Das Gitter selbst ist vereinfacht;
%Vor%was zu einer Zeichnung wie folgt führt:
%Vor%Post-Bounty bearbeiten:
Siehe GIF. Die angenommene Antwort funktioniert. Die Verzögerung ist meine Schuld, der Bildschirm wird nicht aktualisiert (noch) Mauszeiger und die Bildrate ist niedrig-ish. Es bringt eindeutig die richtige Kachel zurück.
Interessante Aufgabe.
Lasst uns versuchen, es zu vereinfachen - lasst uns diesen konkreten Fall lösen
Arbeitsversion ist hier: Ссылка (Änderungen Ссылка )
Zunächst ist Folgendes zu beachten:
Nur zwei Schritte:
Wir brauchen hier zwei Funktionen:
Erkennt Spalte:
%Vor%Funktion, die ein Array von Kacheln extrahiert, die dieser Spalte entsprechen.
Bild um 45 Grad drehen. Die roten Zahlen sind SpalteNr. 3 Spalte ist markiert. X-Achse ist horizontal
%Vor%Eine Liste der zu prüfenden Kacheln ist fertig. Jetzt müssen wir für jede Kachel eine obere Linie finden. Wir haben auch zwei Arten von Fliesen: links und rechts. Wir haben diese Informationen bereits beim Erstellen übereinstimmender Kacheln gespeichert.
%Vor%Bitte verurteile mich nicht, weil ich keinen Code poste. Ich schlage nur einen Algorithmus vor, der es ohne hohen Speicherverbrauch lösen kann.
Der Algorithmus:
Um zu bestimmen, welche Kachel sich in der Maus befindet, müssen wir nicht alle Kacheln überprüfen. Zuerst denken wir, dass die Oberfläche 2D ist und finde heraus, welche Kachel der Mauszeiger mit der veröffentlichten Formel OP überfliegt. Dies ist der am weitesten wahrscheinliche Kachel -Mauscursor, der auf diese Cursorposition zeigen kann.
Diese Kachel kann den Mauszeiger empfangen, wenn sie sich in Höhe 0 befindet. Durch Überprüfung der aktuellen Höhe können wir überprüfen, ob sie wirklich in der Höhe ist, um den Zeiger zu erhalten, wir markieren ihn und bewegen uns vorwärts.
Dann finden wir die nächste wahrscheinliche Kachel, die näher am Bildschirm ist, indem Sie abhängig von der Cursorposition x, y Gitterwerte inkrementieren oder dekrementieren.
Dann bewegen wir uns im Zickzack vorwärts, bis wir eine Kachel erreichen, die selbst bei maximaler Höhe keinen Zeiger aufnehmen kann.
Wenn wir diesen Punkt erreichen, ist das letzte gefundene Kachel , das sich auf einer Höhe befindet, um den Zeiger zu erhalten, die Kachel, nach der wir suchen.
In diesem Fall haben wir nur 8 Kacheln überprüft , um festzustellen, welche Kachel gerade Zeiger empfängt. Dies ist im Vergleich zur Überprüfung aller im Raster vorhandenen Kacheln sehr speichereffizient und führt zu schnelleren Ergebnissen.
Eine Möglichkeit, dies zu lösen, wäre, dem Strahl zu folgen, der von dem angeklickten Pixel auf dem Bildschirm in die Karte geht. Bestimmen Sie dazu einfach die Kameraposition in Bezug auf die Karte und die Blickrichtung:
%Vor%Der nächste Schritt besteht darin, die Berührungsposition in der 3D-Welt zu erhalten. In dieser bestimmten Perspektive ist das ganz einfach:
%Vor%Jetzt müssen Sie nur noch dem Strahl in die Ebene folgen (skalieren Sie die Richtungen so, dass sie kleiner als eine Ihrer Kachendimensionen sind):
%Vor% Nimm jetzt die Kachel bei xz
und überprüfe, ob y
kleiner ist als ihre Höhe;
Ich hatte dieselbe Situation in einem Spiel. Zuerst versuchte ich mit Mathematik, aber als ich feststellte, dass die Kunden jeden Tag den Kartentyp ändern wollten, änderte ich die Lösung mit einer grafischen Lösung und übergab sie dem Designer des Teams. Ich habe die Mausposition erfasst, indem ich auf die SVG-Elemente geklickt habe.
Die Hauptgrafik, die direkt verwendet wird, um die Mausposition zu erfassen und auf das gewünschte Pixel zu übertragen.
Hier ist der Gittereingang, den ich für diese Diskussion definieren würde. Die Ausgabe sollte eine Kachel (coordinate_1, coordinate_2) basierend auf der Sichtbarkeit auf dem Benutzerbildschirm der Maus sein:
Ich kann zwei Lösungen aus verschiedenen Perspektiven anbieten, aber Sie müssen diese in Ihre Problemdomäne zurückkonvertieren. Die erste Methode basiert auf dem Einfärben von Kacheln und kann nützlicher sein, wenn sich die Karte dynamisch ändert. Die zweite Lösung basiert auf Zeichnungskoordinaten-Begrenzungsrahmen basierend auf der Tatsache, dass Kacheln, die näher an dem Betrachter sind, wie (0, 0) niemals durch Kacheln dahinter (1,1) verdeckt werden können.
Ansatz 1: Transparent gefärbte Fliesen
Der erste Ansatz basiert auf dem Zeichnen und Ausarbeiten von hier . Ich muss @haldagan für eine besonders schöne Lösung danken. Zusammenfassend beruht es darauf, eine vollkommen undurchsichtige Schicht auf der ursprünglichen Leinwand zu zeichnen und jede Fliese mit einer anderen Farbe einzufärben. Diese oberste Ebene sollte den gleichen Höhentransformationen wie die darunter liegende Ebene unterliegen. Wenn Sie mit der Maus über eine bestimmte Ebene fahren, können Sie die Farbe über die Leinwand und damit die Kachel selbst erkennen. Dies ist die Lösung, mit der ich wahrscheinlich gehen würde, und das scheint ein nicht so seltenes Problem in der Computervisualisierung und Grafik zu sein (das Finden von Positionen in einer isometrischen 3D-Welt).
Ansatz 2: Ermitteln der Begrenzungsfläche
Dies basiert auf der Vermutung, dass die "vordere" Reihe niemals durch dahinter liegende "hintere" Reihen verdeckt werden kann. Darüber hinaus können "näher zum Bildschirm" -Kacheln nicht durch Kacheln "weiter vom Bildschirm entfernt" verdeckt werden. Um die Bedeutung von "vorne", "zurück", "näher am Bildschirm" und "weiter vom Bildschirm entfernt" zu verdeutlichen, werfen Sie einen Blick auf Folgendes:
Ausgehend von diesem Prinzip wird eine Reihe von Polygonen für jede Kachel erstellt. Zuerst bestimmen wir die Koordinaten auf der Leinwand von nur Box (0, 0) nach der Höhenskalierung. Beachten Sie, dass der Vorgang der Höhenskala einfach ein Trapez ist, das vertikal basierend auf der Höhe gestreckt wird.
Dann bestimmen wir die Koordinaten auf der Leinwand der Boxen (1, 0), (0, 1), (1, 1) nach der Höhenskalierung (wir müssten alles von jenen Polygonen subtrahieren, die sich mit dem Polygon überschneiden) , 0)).
Fahren Sie fort, um die Begrenzungskoordinaten der Boxen zu erstellen, indem Sie alle Okklusionen von Polygonen, die näher am Bildschirm liegen, subtrahieren, um schließlich die Koordinaten von Polygonen für alle Boxen zu erhalten.
Mit diesen Koordinaten und etwas Sorgfalt können Sie schließlich bestimmen, auf welche Kachel durch einen binären Suchstil durch überlappende Polygone gezeigt wird, indem Sie die unteren Reihen nach oben durchsuchen.
Es ist auch wichtig, was sonst auf dem Bildschirm angezeigt wird. Mathe-Versuche funktionieren, wenn Ihre Fliesen ziemlich einheitlich sind. Wenn Sie jedoch verschiedene Objekte anzeigen und möchten, dass der Benutzer sie auswählt, ist es viel einfacher, eine leinwandgroße Zuordnung von Bezeichnern zu haben.
Hier ist die "id" eine einfache x+1+(y+1)*10
(also ist es schön, wenn sie angezeigt wird) und passt in ein Byte (Uint8Array), das bis zu 15x15 Display Grid bereits reichen kann, und es gibt auch breitere Typen.
(Ich habe versucht, es klein zu zeichnen, und es sah auf dem Snippet-Editor-Bildschirm gut aus, aber anscheinend ist es hier immer noch zu groß)
Tags und Links javascript canvas isometric mouse noise