Suchen Sie den Punkt auf einem Kreis mit dem angegebenen Mittelpunkt, Radius und Grad


82

Es ist 10 Jahre her, seit ich so etwas Mathe gemacht habe ... Ich programmiere ein Spiel in 2D und bewege einen Spieler herum. Während ich den Player bewege, versuche ich, den Punkt auf einem Kreis 200 Pixel von der Playerposition entfernt zu berechnen, wenn ein positiver ODER negativer Winkel (Grad) zwischen -360 und 360 vorliegt. Der Bildschirm ist 1280 x 720, wobei 0,0 der Mittelpunkt ist des Bildschirms. Der Spieler bewegt sich um dieses gesamte kartesische Koordinatensystem. Der Punkt, den ich zu finden versuche, kann außerhalb des Bildschirms liegen.

Ich habe die Formeln im Artikel ausprobiert. Finde den Punkt mit Radius und Winkel, aber ich glaube nicht, dass ich verstehe, was "Winkel" ist, weil ich seltsame Ergebnisse erhalte, wenn ich den Winkel als -360 bis 360 in einen Cos (Winkel) oder eine Sünde übergebe (Winkel).

So habe ich zum Beispiel ...

  • 1280x720 in einem kartesischen Flugzeug
  • Mittelpunkt (die Position des Spielers):
    • sei x = eine Zahl zwischen Minimum -640 und Maximum 640
    • sei y = eine Zahl zwischen Minimum -360 und Maximum 360
  • Kreisradius um den Spieler: sei r immer = 200
  • Winkel: a = eine Zahl zwischen -360 und 360 (lassen Sie das Negative nach unten oder das Positive nach oben zeigen, damit -10 und 350 die gleiche Antwort geben)

Wie lautet die Formel, um X auf dem Kreis zurückzugeben?

Wie lautet die Formel, um Y auf dem Kreis zurückzugeben?

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein


16
Das ist eine gute Frage !!! +1
FrostyFire

Frage: Haben die meisten Spiele keine Koordinaten oben links auf 0,0? und y-Achse geht runter, nicht rauf?
Persijn

Antworten:


73

Die einfachen Gleichungen aus Ihrem Link geben die X- und Y-Koordinaten des Punkts auf dem Kreis relativ zum Mittelpunkt des Kreises an .

X = r * cosine(angle)  
Y = r * sine(angle)

Hier erfahren Sie, wie weit der Punkt vom Mittelpunkt des Kreises versetzt ist. Da Sie die Koordinaten des Zentrums (Cx, Cy) haben, fügen Sie einfach den berechneten Versatz hinzu.

Die Koordinaten des Punktes auf dem Kreis sind:

X = Cx + (r * cosine(angle))  
Y = Cy + (r * sine(angle))

1
Meine Verwirrung war zuerst der Unterschied zwischen ANGLE und DEGREE. Ich dachte, sie wären dasselbe. Dann dachte ich, ich würde den Punkt (x, y) in der Ebene bekommen, aber ich würde tatsächlich die Länge der Seiten von x und y bekommen. Ich zog es auf Papier heraus und ließ es dann in Excel fallen, um den Gradbereich abzudecken und die Formeln zu überprüfen. Es funktioniert jetzt in meinem Code.
Kyle Anderson

3
Sollte nicht X = xcircle + (r * sine(angle))sein X = xcircle + (r * cosine(angle))(und umgekehrt für die Y)?
txtechhelp

4
Beachten Sie, dass der Winkel ein Wert im Bogenmaß sein sollte!
Roman M

17

Sie sollten den von Ihnen verwendeten Code veröffentlichen. Das würde helfen, das Problem genau zu identifizieren.

Da Sie jedoch erwähnt haben, dass Sie Ihren Winkel in Bezug auf -360 bis 360 messen, verwenden Sie wahrscheinlich die falschen Einheiten für Ihre Mathematikbibliothek. Die meisten Implementierungen von Trigonometriefunktionen verwenden Bogenmaß für ihre Eingabe. Und wenn Sie stattdessen Grad verwenden ... werden Ihre Antworten seltsam falsch sein.

x_oncircle = x_origin + 200 * cos (degrees * pi / 180)
y_oncircle = y_origin + 200 * sin (degrees * pi / 180)

Beachten Sie, dass Sie möglicherweise auch auf Umstände stoßen, in denen der Quadrant nicht Ihren Erwartungen entspricht. Dies kann behoben werden, indem Sie sorgfältig auswählen, wo sich der Winkel Null befindet, oder indem Sie den erwarteten Quadranten manuell überprüfen und Ihre eigenen Vorzeichen auf die Ergebniswerte anwenden.


1
Dies sollte eigentlich eher ein Kommentar als eine Antwort sein. Allerdings schöner Fang im Bogenmaß gegen Grad.
yoozer8

Zombie-Post-Frage: In Parens, ist das (deg * (pi / 180))oder anders ((deg * pi) / 180)? Vielen Dank auch für die Angabe des Unterschieds zwischen rad und deg.
Montag,

@monsto Zombies senden weiterhin Benachrichtigungen. :). Die inneren Parens spielen keine Rolle, da Multiplikation und Division kommutative Demonstrationen sind. Wolfram.com/… . Ich bin lange schuldig, übermäßige Parens in meinen Code aufgenommen zu haben. Ich gebe vor, es sei aus Gründen der Klarheit, aber das ist eindeutig nicht ganz richtig, sonst hätten Sie sich nicht darum gekümmert.
Seth Battin

6

Ich empfehle dringend, Matrizen für diese Art von Manipulationen zu verwenden. Dies ist der allgemeinste Ansatz, siehe Beispiel unten:

// The center point of rotation
var centerPoint = new Point(0, 0);
// Factory method creating the matrix                                        
var matrix = new RotateTransform(angleInDegrees, centerPoint.X, centerPoint.Y).Value;
// The point to rotate
var point = new Point(100, 0);
// Applying the transform that results in a rotated point                                      
Point rotated = Point.Multiply(point, matrix); 
  • Nebenbei bemerkt, die Konvention besteht darin, den Winkel gegen den Uhrzeigersinn zu messen, beginnend mit der (positiven) X-Achse

5

Ich erhalte seltsame Ergebnisse, wenn ich Angle als -360 bis 360 in einen Cos (Winkel) oder Sin (Winkel) übergebe.

Ich denke, der Grund, warum Ihr Versuch nicht funktioniert hat, ist, dass Sie Winkel in Grad passiert haben. Die sinund costrigonometrischen Funktionen erwarten Winkel im Bogenmaß, daher sollten die Zahlen von 0bis sein 2*M_PI. Für dAbschlüsse, die Sie bestehen M_PI*d/180.0. M_PIist eine im math.hHeader definierte Konstante .


Ich nahm an, dass Winkel und Grad wahrscheinlich nicht dasselbe sind. Bin ich also richtig, wenn ich Angle = M_PI * d / 180.0 sage, wobei d eine Zahl von -360 bis 360 sein kann, oder brauche ich einen weiteren Schritt?
Kyle Anderson

1
@Kyle dist von 0bis 360oder von -180bis 180(ein vollständiger Kreis), nicht von -360bis 360(zwei vollständige Kreise).
Sergey Kalinichenko

4

Ich brauchte dies auch, um die Bewegung der Zeiger einer Uhr im Code zu formen. Ich habe verschiedene Formeln ausprobiert, aber sie haben nicht funktioniert. Deshalb habe ich mir Folgendes ausgedacht:

  • Bewegung - im Uhrzeigersinn
  • Punkte - alle 6 Grad (weil 360 Grad geteilt durch 60 Minuten 6 Grad sind)
  • Handlänge - 65 Pixel
  • Mitte - x = 75, y = 75

Die Formel wäre also

x=Cx+(r*cos(d/(180/PI))
y=Cy+(r*sin(d/(180/PI))

Dabei sind x und y die Punkte auf dem Umfang eines Kreises, Cx und Cy die x-, y-Koordinaten des Zentrums, r der Radius und d die Gradzahl.


2

Hier ist die c # -Implementierung. Das Verfahren wird die kreisförmigen Punkte zurück , die nimmt radius, centerund angle intervalals Parameter. Der Winkel wird als Radian übergeben.

public static List<PointF> getCircularPoints(double radius, PointF center, double angleInterval)
        {
            List<PointF> points = new List<PointF>();

            for (double interval = angleInterval; interval < 2 * Math.PI; interval += angleInterval)
            {
                double X = center.X + (radius * Math.Cos(interval));
                double Y = center.Y + (radius * Math.Sin(interval));

                points.Add(new PointF((float)X, (float)Y));
            }

            return points;
        }

und das aufrufende Beispiel:

List<PointF> LEPoints = getCircularPoints(10.0f, new PointF(100.0f, 100.0f), Math.PI / 6.0f);

ACHTUNG, dass dies aufgrund von Rundungsfehlern 1 Artikel weniger als erwartet zurückgeben kann! Ich habe daher etwas Maring hinzugefügt, damit ich am Ende die richtige Menge an Gegenständen bekomme (mein Beispiel hat Floats anstelle von Double). für (Gleitintervall = Winkelintervall; Intervall <2 * Math.PI + 0,0000099f; Intervall + = Winkelintervall)
Sommmen

1

Ich wollte mitteilen, wie Ihre obigen Beiträge mir geholfen haben, einen Arduino LCD-Kompass herzustellen. Ich hoffe, das ist die richtige Etikette ... Ich bin gerade zu stackoverflow gekommen, damit ich mich bei Ihnen bedanken kann.

Während ich auf den Schultern der Geometrieriesen oben stand, konnte ich diesen Beispielkompass herstellen: Arduino TFT-Kompass mit mehreren Lagern

Der Code für die Funktion, die ich wiederholt aufgerufen habe (für verschiedene Lager sehen Sie in winzigem gelbem Text), ist in Arduino geschrieben (ein bisschen wie "C") ... und ist ziemlich übersetzbar:

void PaintCompassNeedle( int pBearingInDegrees, int pRadius, TSPoint pCentrePt ) {
    // ******************************************************************************
    // * Formula for finding pointX on the circle based on degrees around the circle:
    // * x_oncircle = x_origin + radius * cos (degrees * pi / 180)  
    // * y_oncircle = y_origin - radius * sin (degrees * pi / 180) //minus explained
    // * Thanks to folks at stackoverflow...standing on the shoulders of giants. :) 

    float bearingInRads = (pBearingInDegrees) * PI / 180; 
    // Degrees vs Rads...The math folks use Rads in their formulas

    // *******************************************************************
    // * bearingPt is the point on the circle that we are trying to find
    TSPoint bearingPt;
    // Find the X on the circle starting with orgin (centre)
    bearingPt.x = pCentrePt.x + pRadius * sin(bearingInRads); 
    // Notice the "minus" R * cos()...because TFT the y is upside down bearingPt.y = 
    pCentrePt.y - pRadius * cos(bearingInRads); 
    // * Extra Explanation: The TFT is the graphical display I'm using and it
    // * calculates x & y from the top left of screen (portrait mode) as (0,0)
    // * ...so by Subtracting from the Y orgin...I flip it vertically
    // * Other folks using x,y as increasing to the right and up respectively
    // * would keep the plus sign after the pCentrePt.y
    // *************************************************************************

    // ***************************************************************
    // * This part will change for the final product...but leaving
    // * it because when call numerous times it shows it working for
    // * a number of different quadrants (displaying yellow degrees text)
    tft.fillCircle( bearingPt.x, bearingPt.y, 5, RED); 
    tft.setCursor( bearingPt.x, bearingPt.y );
    tft.setTextSize( 1 );
    tft.setTextColor( YELLOW );
    tft.print( pBearingInDegrees );

    TSPoint innerPt;
    innerPt.x = pCentrePt.x + pRadius/2 * sin(bearingInRads);
    innerPt.y = pCentrePt.y - pRadius/2 * cos(bearingInRads);
    tft.drawLine(innerPt.x, innerPt.y, bearingPt.x, bearingPt.y, RED);

}

0

Die Antwort sollte genau umgekehrt sein.

X = Xc + rSin (Winkel)

Y = Yc + rCos (Winkel)

Dabei sind Xc und Yc die Mittelpunktskoordinaten des Kreises und r der Radius.


0

Empfehlen:

 public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 
pivot, Vector3 angles)
    {
	    return Quaternion.Euler(angles) * (point - pivot) + pivot;
    }


-3

Sie können dies verwenden:

Kreisgleichung wo

(xk) 2 + (yv) 2 = R 2

wobei k und v konstant sind und R der Radius ist

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.