Hinzugefügt am 12. Dezember um 7:00 Uhr Wir haben die in den Kommentaren genannten Fehler korrigiert. (Wir haben den Fall nicht berücksichtigt, in dem die minimale Ausrichtung der Überwachungskamera weniger als 0 ° und die maximale Ausrichtung 360 ° oder mehr beträgt.) Es tut mir sehr leid, dass ich es mit unzureichender Bestätigung gepostet habe.
Wir haben eine Überwachungskamera entwickelt, die nicht an den gesunden Menschenverstand gebunden ist und es den Menschen ermöglicht, vor ihnen hindurchzugehen.
import java.util.Scanner;
class CameraTest {
public static void main(String[] args) {
//Eingang
Scanner sc = new Scanner(System.in);
//Spieler
double px = sc.nextDouble(); //Spieler x Koordinaten
double py = sc.nextDouble(); //Spieler y Koordinate
Player player = new Player(px, py);
//Überwachungskamera
int N = sc.nextInt(); //Anzahl der Überwachungskameras
for (int n = 0; n < N; n ++) {
//Eingabe / Verarbeitung für jede Überwachungskamera
double x = sc.nextDouble(); //Überwachungskamera x Koordinaten
double y = sc.nextDouble(); //Überwachungskamera y Koordinate
double d = sc.nextDouble(); //Entfernung, die die Überwachungskamera sehen kann
double e = sc.nextDouble(); //Ausrichtung der Überwachungskamera(direction)Winkel darstellend
double f = sc.nextDouble(); //Betrachtungswinkel der Überwachungskamera
Camera camera = new Camera(x, y, d, e, f);
if (camera.findPlayer(player)) {
System.out.println("Ich konnte sehen");
} else {
System.out.println("Ich konnte nicht sehen");
}
}
sc.close();
}
}
class Player {
private double x; //Spieler x Koordinaten
private double y; //Spieler y Koordinate
public Player(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
}
class Camera {
private double x; //Überwachungskamera x Koordinaten
private double y; //Überwachungskamera y Koordinate
private double distance; //Entfernung, die die Überwachungskamera sehen kann
private double dirAngle; //Ausrichtung der Überwachungskamera(direction)Winkel darstellend
private double viewAngle; //Betrachtungswinkel der Überwachungskamera
public Camera(double x, double y, double d, double e, double f) {
this.x = x;
this.y = y;
this.distance = d;
this.dirAngle = e;
this.viewAngle = f;
}
public boolean findPlayer(Player player) {
double px = player.getX();
double py = player.getY();
//Beurteilung nach Entfernung
double d = Math.sqrt(Math.pow(this.x - px, 2) + Math.pow(this.y - py, 2));
if (d > this.distance) {
return false;
}
//Beurteilung nach Winkel
double a = Math.toDegrees(Math.atan2(py - this.y, px - this.x));
double aMin = this.dirAngle - this.viewAngle/2;
double aMax = this.dirAngle + this.viewAngle/2;
if (a < aMin || aMax < a) {
return false;
}
return true;
}
}
Das größte schlechte an __ in dieser Programmierung ist, dass ich die Bibliothek mehrdeutig verwendet habe, ohne sie überhaupt zu untersuchen. Versteh mich nicht falsch, es ist nicht schlecht, eine Bibliothek zu benutzen (vielmehr ist es viel effizienter, sie zu benutzen, als deine eigenen seltsamen Methoden zu erstellen). __ Es ist schlecht, es zu benutzen, ohne es nachzuschlagen __. Mal sehen, welcher Teil schlecht war. Zusammenfassend ist es der Teil, der die atan2-Methode der Bibliothek bei der Beurteilung anhand des Winkels in der findPlayer-Methode der Camera-Klasse verwendet. Achten wir auf den Rückgabewert dieser Methode.
Von der Oracle-Website * Das Erscheinungsbild wurde geringfügig geändert, um das Lesen zu erleichtern. https://docs.oracle.com/javase/jp/1.4/api/java/lang/Math.html#atan2(double,%20double)
public static double atan2 (double y, double x) (zum Öffnen klicken) summary>
Konvertiert orthogonale Koordinaten (x, y) in Polarkoordinaten (r, Theta). Diese Methode berechnet die inverse Tangente (Bogen-Tangente) von y / x im Bereich __- pi bis pi __ font>, um das Phasentheta zu ermitteln. Als Sonderfall-Wenn eines der Argumente NaN ist, ist das Ergebnis NaN. -Wenn das erste Argument positiv Null ist und das zweite Argument positiv ist oder das erste Argument positiv endlich ist und das zweite Argument positiv unendlich ist, ist das Ergebnis positiv null. -Wenn das erste Argument eine negative Null und das zweite Argument positiv ist oder das erste Argument negativ endlich ist und das zweite Argument positiv unendlich ist, ist das Ergebnis eine negative Null. -Wenn das erste Argument positiv Null und das zweite Argument negativ ist oder das erste Argument positiv endlich ist und das zweite Argument negativ unendlich ist, ist das Ergebnis ein doppelter Wert, der pi am ähnlichsten ist. Werden. -Wenn das erste Argument negativ Null und das zweite Argument negativ ist oder das erste Argument negativ endlich ist und das zweite Argument negativ unendlich ist, ist das Ergebnis ein doppelter Wert, der -pi am ähnlichsten ist. Wird sein. -Wenn das erste Argument positiv und das zweite Argument positiv oder negativ Null ist oder das erste Argument positiv unendlich ist und das zweite Argument endlich ist, ist das Ergebnis ein Doppel, das pi / 2 am ähnlichsten ist. Es wird ein Wert sein. -Wenn das erste Argument negativ und das zweite Argument positiv oder negativ Null ist oder das erste Argument negativ unendlich ist und das zweite Argument endlich ist, ist das Ergebnis am nächsten an -pi / 2. Es wird ein doppelter Wert sein. -Wenn beide Argumente positiv unendlich sind, ist das Ergebnis ein doppelter Wert, der pi / 4 am nächsten kommt. -Wenn das erste Argument positiv unendlich und das zweite Argument negativ unendlich ist, ist das Ergebnis der Doppelwert, der 3 * pi / 4 am nächsten kommt. -Wenn das erste Argument eine negative Unendlichkeit und das zweite Argument eine positive Unendlichkeit ist, ist das Ergebnis der Doppelwert, der -pi / 4 am nächsten kommt. -Wenn beide Argumente negativ unendlich sind, ist das Ergebnis ein doppelter Wert, der -3 * pi / 4 am nächsten kommt.
Das Ergebnis muss innerhalb von 2 ulp des korrekt gerundeten Ergebnisses liegen. Die Ergebnisse sind auf halb eintönig beschränkt.
__ Parameter: __ y - Vertikale Koordinaten x-horizontale Koordinaten Rückgabewert: Theta-Komponente des Punktes (r, Theta) auf den Polarkoordinaten entsprechend dem Punkt (x, y) auf den orthogonalen Koordinaten (Dekartkoordinaten)
Der Punkt ist, dass Sie, wenn Sie nur die Umkehrfunktion von tan (die atan-Methode der Bibliothek) verwenden, nur die __direction __ [^ 1] des Vektors kennen können, der die $ x $ -Komponente und die $ y $ -Komponente des Arguments enthält. Sie müssen auch das Vorzeichen jeder Komponente betrachten, um die __direction __ [^ 1] des Vektors herauszufinden. Die atan2-Methode implementiert einen so wunderbaren Prozess. [^ 1]: In der Welt der Mathematik und Physik gibt es eine klare Unterscheidung zwischen "Richtung" und "Richtung". Wenn es beispielsweise eine Straße gibt, die zwei Punkte verbindet, ist die Straße selbst die "Richtung", und die Unterscheidung zwischen der Fahrspur, auf der Sie sich befinden, und der gegenüberliegenden Fahrspur ist die "Richtung" (Nord-Süd- "Richtung" usw. Es heißt "Richtung" im Norden und "Richtung" im Süden.
Der wichtigste Teil ist der fettgedruckte Rückgabewert, und der Bereich von -pi bis pi ist der Winkel, der durch die Bogengradmethode [^ 2] ausgedrückt wird, die in die Frequenzmethode [^ 2] umgewandelt wird. Bei der Konvertierung (toDegrees-Methode der Bibliothek) beträgt sie -180 ° bis 180 °. Wenn Sie etwas genauer hinschauen, wenn die $ x $ -Komponente -1 und die $ y $ -Komponente 0 ist, wird der von der atan2-Methode zurückgegebene Wert von der toDegrees-Methode in die Frequenzmethode konvertiert und wird zu 180.0, sodass er nach links zeigt. Scheint 180 ° statt -180 ° für den Vektor von zu sein. Mit anderen Worten, es wird ein Wert zurückgegeben, der größer als __- 180 ° und kleiner als 180 ° __ ist. [^ 2]: Grob gesagt ist die Bogengradmethode diejenige, die den zentralen Winkel der Gänseform mit einem Radius von 1 und der Bogenlänge von 1 als 1 Bogenmaß bestimmt, und die Frequenzmethode ist diejenige, die wir normalerweise verwenden, 1 Der Umfang ist auf 360 ° eingestellt. Da der Umfang des Radius 1 2 $ \ pi $ beträgt, repräsentiert der Bogenmaß 2 $ \ pi $ einen Winkel von bis zu 360 °.
Ich bin endlich zum Kern gekommen. Ich entschied zuerst, dass der Betrachtungswinkel der Überwachungskamera __0 ° oder mehr und weniger als 360 ° __ betrug. Die vom Programm erhaltene Ausrichtung des Spielers war jedoch größer als __- 180 ° und kleiner als 180 ° __. Verwenden wir das Beispiel, das beim letzten Mal fehlgeschlagen ist, um es zu überprüfen und gleichzeitig den Winkel anzuzeigen, der die Ausrichtung des Players darstellt.
10 16 8 270 120 a = -90.0 aMin = 210.0, aMax = 330.0 Ich konnte nicht sehen
Das war's. Die Überwachungskamera deckt den Bereich von 210 ° oder mehr und 330 ° oder weniger ab, aber der Player wird als Winkel außerhalb des Bereichs berechnet, sodass er durchlaufen wurde. Lassen Sie uns nun überlegen, was zu tun ist, wenn der Winkel, der die Ausrichtung des Spielers darstellt, außerhalb des Betrachtungswinkels der Überwachungskamera liegt, dh größer als __- 180 ° und kleiner als 0 ° __. Erstens, da negative Winkel im Alltag selten verwendet werden, können einige Menschen überfordert sein, aber sobald das Prinzip verstanden ist, ist es nicht so schwierig. Einfach ausgedrückt ist es nur ein positiver Winkel, wenn es gegen den Uhrzeigersinn gedreht wird, und ein negativer Winkel, wenn es im Uhrzeigersinn gedreht wird. Zum Beispiel ist das Drehen um 90 ° im Uhrzeigersinn letztendlich dasselbe wie das Drehen um 270 ° gegen den Uhrzeigersinn. Die um -90 ° gedrehte Position entspricht der um 270 ° gedrehten Position. Wenn es größer als __- 180 ° und kleiner als 0 ° ist, besteht die richtige Antwort darin, 360 ° hinzuzufügen und auf den Bereich von 0 ° oder mehr und weniger als 360 ° zu korrigieren.
Problem Nr. 2
Nachdem wir den Winkel überprüft haben, der die Ausrichtung des Players darstellt, ist der nächste Schritt die Ausrichtung der Überwachungskamera. Betrachten Sie beispielsweise das folgende Beispiel.
- Wenn die Ausrichtung der Überwachungskamera 10 ° und der Betrachtungswinkel 60 ° beträgt, beträgt der Ausrichtungsbereich der Überwachungskamera -20 ° bis 40 °, sodass der Ausrichtungsbereich der Überwachungskamera 0 ° bis 40 ° betragen sollte. Es ist notwendig, durch Teilen in zwei, 340 ° bis 360 ° zu beurteilen.
- Wenn die Ausrichtung der Überwachungskamera 350 ° und der Betrachtungswinkel 60 ° beträgt, beträgt der Ausrichtungsbereich der Überwachungskamera 320 ° bis __380 ° __, sodass der Ausrichtungsbereich der Überwachungskamera 320 ° bis 360 ° beträgt. Es ist notwendig, durch Teilen in zwei, 0 ° bis 20 ° zu beurteilen.
...... Ich habe Kopfschmerzen, wenn ich nur daran denke, aber ich kann es nicht vermeiden. Die Verarbeitung muss hinzugefügt werden, damit der Player auch dann sichtbar ist, wenn er weniger als 0 ° oder mehr als 360 ° beträgt. Schreiben Sie nun in der findPlayer-Methode den Teil neu, der die Beurteilung basierend auf dem Winkel wie folgt vornimmt.
public boolean findPlayer(Player player) { //Unterlassung //Beurteilung nach Winkel double a = Math.toDegrees(Math.atan2(py - this.y, px - this.x)); if (a < 0) { a += 360.0; } System.out.println("a = " + a); double aMin = this.dirAngle - this.viewAngle/2; if (aMin < 0.0) { //Wenn die minimale Kameraausrichtung negativ ist, wird aMin+Stellen Sie fest, ob es im Bereich von 360 bis 360 sichtbar ist aMin += 360; if (aMin <= a && a < 360.0) { return true; } //Danach aMin+Sie müssen nicht über den Bereich von 360-360 nachdenken aMin = 0.0; } double aMax = this.dirAngle + this.viewAngle/2; if (aMax >= 360.0) { //0 bis aMax, wenn die maximale Ausrichtung der Kamera 360 oder mehr beträgt-Stellen Sie fest, ob es im Bereich 360 sichtbar ist aMax -= 360.0; if (0.0 <= a && a <= aMax) { return true; } //Danach 0 bis aMax-Sie müssen nicht an die 360-Serie denken aMax = 360.0; } System.out.println("aMin = " + aMin + ", aMax = " + aMax); if (aMin <= a && a <= aMax) { return true; } return false; }
Wie in Problem 1 erläutert, addieren Sie 360, nachdem Sie die Ausrichtung des Spielers (Variable a) gefunden haben, wenn der Wert negativ ist. Dies stellt sicher, dass die Ausrichtung des Spielers immer größer oder gleich 0 ° und kleiner als 360 ° ist. Nachdem Sie die minimale Ausrichtung der Kamera (Variable aMin) ermittelt haben und der Wert weniger als 0 ° beträgt, bestimmen Sie zunächst, ob der Player im Bereich von aMin + 360 ° oder mehr und weniger als 360 ° gesehen werden kann und ob er wahr ist. Gibt zurück (überspringt den Rest des Prozesses). Wenn es nicht sichtbar ist, muss der verbleibende Bereich beurteilt werden, damit der Vorgang fortgesetzt wird. Da der Bereich von aMin + 360 ° oder mehr und weniger als 360 ° nicht mehr berücksichtigt werden muss, wird aMin auf 0 ° gesetzt. Infolgedessen wird es später sogar im Bereich von 0 ° oder mehr und aMax oder weniger beurteilt. Gleiches gilt für die maximale Kameraausrichtung (Variable aMax).
3. 3. Komplett
Es ist ein Programm, das die bisherige Überprüfung widerspiegelt. Es war lang ……… ~~ Eigentlich war es ein Umweg ~~
Sichtbarkeitsprogramm für wiedergeborene Spieler (zum Öffnen klicken) summary>
import java.util.Scanner; class CameraTest { public static void main(String[] args) { //Eingang Scanner sc = new Scanner(System.in); //Spieler double px = sc.nextDouble(); //Spieler x Koordinaten double py = sc.nextDouble(); //Spieler y Koordinate Player player = new Player(px, py); //Überwachungskamera int N = sc.nextInt(); //Anzahl der Überwachungskameras for (int n = 0; n < N; n ++) { //Eingabe / Verarbeitung für jede Überwachungskamera double x = sc.nextDouble(); //Überwachungskamera x Koordinaten double y = sc.nextDouble(); //Überwachungskamera y Koordinate double d = sc.nextDouble(); //Entfernung, die die Überwachungskamera sehen kann double e = sc.nextDouble(); //Ausrichtung der Überwachungskamera(direction)Winkel darstellend double f = sc.nextDouble(); //Betrachtungswinkel der Überwachungskamera Camera camera = new Camera(x, y, d, e, f); if (camera.findPlayer(player)) { System.out.println("Ich konnte sehen"); } else { System.out.println("Ich konnte nicht sehen"); } } sc.close(); } } class Player { private double x; //Spieler x Koordinaten private double y; //Spieler y Koordinate public Player(double x, double y) { this.x = x; this.y = y; } public double getX() { return this.x; } public double getY() { return this.y; } } class Camera { private double x; //Überwachungskamera x Koordinaten private double y; //Überwachungskamera y Koordinate private double distance; //Entfernung, die die Überwachungskamera sehen kann private double dirAngle; //Ausrichtung der Überwachungskamera(direction)Winkel darstellend private double viewAngle; //Betrachtungswinkel der Überwachungskamera public Camera(double x, double y, double d, double e, double f) { this.x = x; this.y = y; this.distance = d; this.dirAngle = e; this.viewAngle = f; } public boolean findPlayer(Player player) { double px = player.getX(); double py = player.getY(); //Beurteilung nach Entfernung double d = Math.sqrt(Math.pow(this.x - px, 2) + Math.pow(this.y - py, 2)); if (d > this.distance) { return false; } //Beurteilung nach Winkel double a = Math.toDegrees(Math.atan2(py - this.y, px - this.x)); if (a < 0) { a += 360.0; } System.out.println("a = " + a); double aMin = this.dirAngle - this.viewAngle/2; if (aMin < 0.0) { //Wenn die minimale Kameraausrichtung negativ ist, wird aMin+Stellen Sie fest, ob es im Bereich von 360 bis 360 sichtbar ist aMin += 360; System.out.println("aMin = " + aMin + ", aMax = 360.0"); if (aMin <= a && a < 360.0) { return true; } //Danach aMin+Sie müssen nicht über den Bereich von 360-360 nachdenken aMin = 0.0; } double aMax = this.dirAngle + this.viewAngle/2; if (aMax >= 360.0) { //0 bis aMax, wenn die maximale Ausrichtung der Kamera 360 oder mehr beträgt-Stellen Sie fest, ob es im Bereich 360 sichtbar ist aMax -= 360.0; System.out.println("aMin = 0.0, aMax = " + aMax); if (0.0 <= a && a <= aMax) { return true; } //Danach 0 bis aMax-Sie müssen nicht an die 360-Serie denken aMax = 360.0; } System.out.println("aMin = " + aMin + ", aMax = " + aMax); if (aMin <= a && a <= aMax) { return true; } return false; } }
Wenn bei der findPlayer-Methode der Wert der Variablen a, in der der Winkel gespeichert ist, der die Richtung des Players angibt, negativ ist, haben wir gerade den Vorgang des Hinzufügens von 360 hinzugefügt. Und das Ergebnis der Rache.
10 16 8 270 120 a = 270.0 aMin = 210.0, aMax = 330.0 Ich konnte sehen
Es ist perfekt!
4. Diese Lektion
Es ist schwer zu erwähnen, aber dieses Mal werde ich über die Punkte schreiben, die ich besonders gezogen habe.
Überprüfen Sie unbedingt die technischen Daten, wenn Sie etwas verwenden, das von anderen hergestellt wurde!
Dies ist der größte Reflexionspunkt. Ich habe vor langer Zeit etwas über die atan2-Methode gelernt und diesmal zum ersten Mal seit einiger Zeit wieder verwendet, aber der Rückgabewert wurde vollständig durchlaufen. Ich war vielmehr davon überzeugt, dass es bei 0 ° oder mehr und weniger als 360 ° zurückkehren würde. Da ich überzeugt war, habe ich lange gebraucht, um die Ursache zu erkennen. Um weiter zu gestehen, ist es richtig, die Argumente der atan2-Methode in der Reihenfolge von $ y $ -Komponente und $ x $ -Komponente zuzuweisen, aber am Anfang habe ich sie in die entgegengesetzte Richtung gesetzt. Das ist viel. Es wäre beängstigend zu glauben, dass dies ein Entwicklungsstandort war. Der Compiler hat bestanden, aber er hat nicht das Richtige getan. Ich glaube, ich hatte Recht ... Es ist eine Katastrophe. Natürlich bin ich dafür verantwortlich, also kann ich keine Ausreden machen. Wenn Sie also etwas verwenden, das von einer anderen Person hergestellt wurde, überprüfen Sie unbedingt die __- Spezifikation __. In Bezug auf die atan2-Methode muss diesmal herausgefunden werden, was in dem Argument enthalten ist, welche Art von Wert der Rückgabewert ist oder welchen Bereich er hat. Versuchen Sie zu diesem Zeitpunkt, alle Ihre Annahmen zu beseitigen.
Stellen Sie sicher, dass Sie die Spezifikationen klarstellen, wenn Sie möchten, dass andere das verwenden, was Sie gemacht haben!
Dies ist eine Lehre für die Zukunft. Bei der Entwicklung mit einem Team von mehreren Personen muss ordnungsgemäß organisiert werden, welche Art von Eingabe das verantwortliche Programm sein soll, welche Art von Verarbeitung durchgeführt wird und welche Art von Ergebnis ausgegeben wird. Es gibt. Ich denke, es gibt je nach Site verschiedene Regeln, ob Sie es als Kommentar in dem von mir geschriebenen Programm hinterlassen oder als separates Dokument speichern möchten, aber stellen Sie sicher, dass Sie es in irgendeiner Form (selbst) belassen. Sogar die von werden mit der Zeit vergessen!). Andernfalls wird es Ihren Teamkollegen große Probleme bereiten.
5. Am Ende
Neulich, nachdem ich den ersten Teil des Artikels veröffentlicht hatte, lernte ich viel aus den Kommentaren, die ich über Methoden und Verarbeitungsmethoden nicht kannte. Ich werde weiterhin Artikel über Qiita veröffentlichen und mein Bestes geben, damit ich in Zukunft Ratschläge geben kann. Vielen Dank, dass Sie so weit gelesen haben.
Recommended Posts