주어진 중심점, 반지름 및 각도로 원에서 점 찾기
이런 수학을 한 지 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를 반환하는 공식은 무엇입니까?
링크의 간단한 방정식은 원 의 중심을 기준으로 원에있는 점의 X 및 Y 좌표를 제공합니다 .
X = r * cosine(angle)
Y = r * sine(angle)
이것은 점이 원의 중심에서 얼마나 멀리 떨어져 있는지 알려줍니다. 중심 좌표 (Cx, Cy)가 있으므로 계산 된 오프셋을 추가하기 만하면됩니다.
원 위의 점 좌표는 다음과 같습니다.
X = Cx + (r * cosine(angle))
Y = Cy + (r * sine(angle))
사용중인 코드를 게시해야합니다. 문제를 정확히 파악하는 데 도움이됩니다.
그러나 각도를 -360에서 360까지 측정한다고 언급 했으므로 수학 라이브러리에 잘못된 단위를 사용하고있을 수 있습니다. 삼각 함수의 대부분의 구현은 입력에 라디안을 사용합니다. 그리고 학위를 대신 사용하면 ... 당신의 대답은 이상하게 틀릴 것입니다.
x_oncircle = x_origin + 200 * cos (degrees * pi / 180)
y_oncircle = y_origin + 200 * sin (degrees * pi / 180)
사분면이 예상과 다른 상황에 처할 수도 있습니다. 각도 0이 어디에 있는지 신중하게 선택하거나 예상되는 사분면을 수동으로 확인하고 결과 값에 자신의 기호를 적용하여이 문제를 해결할 수 있습니다.
이러한 유형의 조작을 위해 행렬을 사용하는 것이 좋습니다. 가장 일반적인 접근 방식입니다. 아래 예를 참조하십시오.
// 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 축 각도를 측정하는 것입니다.
각도를 -360에서 360으로 Cos (각도) 또는 Sin (각도)에 전달하면 이상한 결과가 나타납니다.
당신의 시도가 효과가 없었던 이유는 당신이 각도를 통과하고 있었기 때문이라고 생각합니다. sin
및 cos
숫자로부터되어야하므로 삼각 함수는 라디안 각도 기대 0
로 2*M_PI
. 의 경우 d
도 당신은 통과 M_PI*d/180.0
. 헤더에 M_PI
정의 된 상수 math.h
입니다.
나는 또한 이것이 코드에서 시계 바늘의 움직임을 형성하는 데 필요했습니다. 몇 가지 공식을 시도했지만 작동하지 않았으므로 다음과 같이 생각해 냈습니다.
- 모션-시계 방향
- 포인트-6 도마 다 (360도를 60 분으로 나눈 값은 6도이므로)
- 손 길이-65 픽셀
- 중심-x = 75, y = 75
그래서 공식은
x=Cx+(r*cos(d/(180/PI))
y=Cy+(r*sin(d/(180/PI))
where x and y are the points on the circumference of a circle, Cx and Cy are the x,y coordinates of the center, r is the radius, and d is the amount of degrees.
Here is the c# implementation. The method will return the circular points which takes radius
, center
and angle interval
as parameter. Angle is passed as 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;
}
and the calling example:
List<PointF> LEPoints = getCircularPoints(10.0f, new PointF(100.0f, 100.0f), Math.PI / 6.0f);
I wanted to share how your contributions above helped me produce an Arduino LCD compass. I hope this is the right etiquette...I just joined stackoverflow so I could thank you fine folks.
While standing on the shoulders of the geometry giants above I was able to produce this sample compass: Arduino TFT compass with multiple bearings
내가 반복적으로 호출 한 함수의 코드 (작은 노란색 텍스트로 표시되는 다른 베어링에 대해)는 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);
}
대답은 정반대 여야합니다.
X = Xc + rSin (각도)
Y = Yc + rCos (각도)
여기서 Xc와 Yc는 원의 중심 좌표이고 r은 반경입니다.
권하다:
public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3
pivot, Vector3 angles)
{
return Quaternion.Euler(angles) * (point - pivot) + pivot;
}
이것을 사용할 수 있습니다 :
원의 방정식
(xk) 2 + (yv) 2 = R 2
여기서 k와 v는 일정하고 R은 반지름입니다.
'developer tip' 카테고리의 다른 글
C ++에서 빈 클래스의 크기가 0이 아닌 이유는 무엇입니까? (0) | 2020.10.23 |
---|---|
--start-group 및 --end-group 명령 줄 옵션은 무엇입니까? (0) | 2020.10.22 |
setTimeout에서 약속을 만드는 방법 (0) | 2020.10.22 |
람다를 비교하는 방법이 있습니까? (0) | 2020.10.22 |
상수에 대한 참조로 예외를 포착하는 이유는 무엇입니까? (0) | 2020.10.22 |