주어진 중심점, 반지름 및 각도로 원에서 점 찾기


82

이런 수학을 한 지 10 년이 지났습니다. 저는 2D로 게임을 프로그래밍하고 플레이어를 움직입니다. 플레이어를 움직일 때 -360에서 360 사이의 양 또는 음의 각도 (도)가 주어지면 플레이어 위치에서 200 픽셀 떨어진 원의 점을 계산하려고합니다. 화면은 1280x720이고 0,0이 중심점입니다. 화면의. 플레이어는이 전체 데카르트 좌표계 주위를 이동합니다. 내가 찾으려고하는 지점은 화면 밖일 수 있습니다.

반지름과 각도가있는 점 찾기 기사의 공식을 시도했지만 각도를 -360에서 360으로 Cos (각도) 또는 Sin에 전달하면 이상한 결과가 나오기 때문에 "각도"가 무엇인지 이해하고 있지 않습니다. (각도).

예를 들어 저는 ...

  • 데카르트 평면에서 1280x720
  • 센터 포인트 (플레이어의 위치) :
    • let x = 최소 -640에서 최대 640 사이의 숫자
    • y = 최소 -360에서 최대 360 사이의 숫자
  • 플레이어 주변의 원 반경 : 항상 r = 200
  • 각도 : a = -360에서 360 사이의 숫자 (음수는 아래쪽을 가리키고 양수는 위쪽을 가리 키도록 허용하므로 -10과 350은 동일한 답을 제공함)

원에 X를 반환하는 공식은 무엇입니까?

원에 Y를 반환하는 공식은 무엇입니까?

여기에 이미지 설명 입력 여기에 이미지 설명 입력


16
이것은 좋은 질문입니다 !!! +1
FrostyFire

1
질문 : 대부분의 게임은 왼쪽 상단에 0,0에 좌표가 있지 않습니까? 그리고 y 축은 위가 아닌 아래로 내려가나요?
Persijn

답변:


73

링크의 간단한 방정식은 원 의 중심을 기준으로 원에있는 점의 X 및 Y 좌표를 제공합니다 .

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

이것은 점이 원의 중심에서 얼마나 멀리 떨어져 있는지 알려줍니다. 중심 좌표 (Cx, Cy)가 있으므로 계산 된 오프셋을 추가하기 만하면됩니다.

원 위의 점 좌표는 다음과 같습니다.

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

1
내 혼란은 ANGLE과 DEGREE의 차이에서 처음이었습니다. 나는 그들이 같은 것이라고 생각했습니다. 그런 다음 나는 비행기에서 점 (x, y)을 얻는다고 생각했지만 실제로 x와 y의 변의 길이를 얻었습니다. 나는 그것을 종이에 그린 다음 수식을 확인하기 위해 각도 범위를 커버하기 위해 엑셀로 떨어 뜨 렸습니다. 이제 내 코드에서 작동합니다.
Kyle Anderson

3
X = xcircle + (r * sine(angle))X = xcircle + (r * cosine(angle))합니다 (및 그 반대 Y)?
txtechhelp

4
각도는 라디안 값이어야합니다!
Roman M

17

사용중인 코드를 게시해야합니다. 문제를 정확히 파악하는 데 도움이됩니다.

그러나 각도를 -360에서 360까지 측정한다고 언급 했으므로 수학 라이브러리에 잘못된 단위를 사용하고있을 수 있습니다. 삼각 함수의 대부분의 구현은 입력에 라디안을 사용합니다. 그리고 학위를 대신 사용하면 ... 당신의 대답은 이상하게 틀릴 것입니다.

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

사분면이 예상과 다른 상황에 처할 수도 있습니다. 각도 0이 어디에 있는지 신중하게 선택하거나 예상되는 사분면을 수동으로 확인하고 결과 값에 자신의 기호를 적용하여이 문제를 해결할 수 있습니다.


1
이것은 답변 이라기보다는 코멘트 여야합니다. 그러나 라디안 대 각도에 대한 좋은 캐치.
yoozer8

좀비 포스트 질문 : 괄호로, 그게 (deg * (pi / 180))아니면 반대 ((deg * pi) / 180)인가요? 또한 rad와 deg 사이의 차이를 지정해 주셔서 감사합니다.
monsto

@monsto 좀비는 여전히 알림을 보냅니다. :). 내부 괄호는 곱셈과 나눗셈이 교환 데모 이기 때문에 중요하지 않습니다 . wolfram.com/… . 나는 내 코드에 과도한 괄호를 넣은 것에 대해 오랫동안 유죄입니다. 나는 그것이 명확성을위한 척하지만 분명히 그것은 엄격하게 사실이 아니거나 당신이 그것에 대해 괴롭히지 않았을 것입니다.
Seth Battin

6

이러한 유형의 조작에는 행렬을 사용하는 것이 좋습니다. 가장 일반적인 접근 방식입니다. 아래 예를 참조하십시오.

// 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); 
  • 참고로, 관례는 시계 반대 방향 시작 형태 (양수) X 축 각도를 측정하는 것입니다.

5

각도를 -360에서 360으로 Cos (angle) 또는 Sin (angle)에 전달하면 이상한 결과가 나타납니다.

당신의 시도가 효과가 없었던 이유는 당신이 각도를 통과하고 있었기 때문이라고 생각합니다. sincos 숫자로부터되어야하므로 삼각 함수는 라디안 각도 기대 02*M_PI. 의 경우 d도 당신은 통과 M_PI*d/180.0. 헤더에 M_PI정의 된 상수 math.h입니다.


각도와 각도가 같지 않다고 생각 했으므로 각도 = M_PI * d / 180.0이라고 말했습니까? 여기서 d는 -360에서 360까지의 숫자가 될 수 있습니까? 아니면 다른 단계가 필요합니까?
Kyle Anderson

1
@Kyle은 d출신 0360또는에서 -180180,하지에서 (완전한 원) -360360(두 개의 완전한 원).
Sergey Kalinichenko

4

코드에서 시계 바늘의 움직임을 형성하는데도 필요했습니다. 몇 가지 공식을 시도했지만 작동하지 않았기 때문에 이것이 제가 생각 해낸 것입니다.

  • 모션-시계 방향
  • 포인트-6 도마 다 (360도를 60 분으로 나눈 값은 6도이므로)
  • 손 길이-65 픽셀
  • 중심-x = 75, y = 75

그래서 공식은

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

여기서 x와 y는 원의 원주에있는 점, Cx와 Cy는 중심의 x, y 좌표, r은 반경, d는 각도의 양입니다.


2

다음은 C # 구현입니다. 이 메서드는 radius, centerangle interval매개 변수를 사용 하는 원형 점을 반환합니다 . 각도는 Radian으로 전달됩니다.

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;
        }

및 호출 예 :

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

반올림 오류로 인해 예상보다 1 개 더 적은 항목이 반환 될 수 있습니다. 따라서 마지막에 올바른 양의 항목을 얻도록 약간의 마링을 추가했습니다 (내 예제에는 double 대신 float가 있습니다). for (float interval = angleInterval; interval <2 * Math.PI + 0.0000099f; interval + = angleInterval)
sommmen

1

위의 기여가 Arduino LCD 나침반을 만드는 데 어떻게 도움이되었는지 공유하고 싶었습니다. 이것이 올바른 에티켓이기를 바랍니다. 저는 여러분 께 감사 할 수 있도록 stackoverflow에 가입했습니다.

위의 지오메트리 거인의 어깨에 서서이 샘플 나침반을 만들 수있었습니다. 여러 베어링이있는 Arduino TFT 나침반

내가 반복적으로 호출 한 함수의 코드 (작은 노란색 텍스트로 표시되는 다른 베어링에 대해)는 Arduino ( "C"와 같은 종류)로 작성되었으며 매우 번역이 가능합니다.

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

대답은 정반대 여야합니다.

X = Xc + rSin (각도)

Y = Yc + rCos (각도)

여기서 Xc와 Yc는 원의 중심 좌표이고 r은 반경입니다.


0

권하다:

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


-3

이것을 사용할 수 있습니다 :

원의 방정식

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

여기서 k와 v는 일정하고 R은 반경입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.