找到具有给定中心点,半径和度数的圆上的点

时间:2012-12-31 00:23:13

标签: c# geometry

自从我做了这样的数学运算已经10年了......我正在编写2D游戏并移动玩家。当我移动玩家时,我试图在距离玩家位置200像素的圆上计算点,给出-360到360之间的正OR负角度(度)。屏幕是1280x720,其中0,0是中心点的屏幕。玩家围绕整个笛卡尔坐标系移动。我试图找到的重点可能是屏幕上的。

我尝试了文章Find the point with radius and angle上的公式,但我不相信我理解“角度”是什么,因为当我将角度-360到360转换为Cos(角度)时,我得到了奇怪的结果或罪(角度)。

例如,我有......

  • 1280x720在笛卡尔平面上
  • 中心点(玩家的位置):
    • 设x =最小-640到最大640之间的数字
    • 令y =最小-360到最大360之间的数字
  • 玩家周围的圆圈半径:让r始终= 200
  • 角度:设a = -360到360之间的数字(允许负数指向下或正数指向上,因此-10和350会给出相同的答案)

在圈子上返回X的公式是什么?

在圈子上返回Y的公式是什么?

enter image description here enter image description here

10 个答案:

答案 0 :(得分:57)

链接中的简单方程式给出了圆上相对于圆心的点的X和Y坐标。

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

这可以告诉您点距离圆心的距离。由于您具有中心坐标(Cx,Cy),只需添加计算的偏移量。

圆上点的坐标为:

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

答案 1 :(得分:12)

您应该发布您正在使用的代码。这有助于准确识别问题。

但是,由于您提到的测量角度为-360到360,因此您可能正在使用数学库中不正确的单位。大多数三角函数的实现使用弧度作为输入。如果你使用学位而不是...你的答案将是奇怪的错误。

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

请注意,您可能还会遇到象限不符合您预期的情况。这可以通过仔细选择角度零的位置来修复,或者通过手动检查您期望的象限并将自己的符号应用于结果值来修复。

答案 2 :(得分: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轴
  • 的角度

答案 3 :(得分:5)

  

当我将角度-360到360传递到Cos(角度)或Sin(角度)时,我得到了奇怪的结果。

我认为你的尝试不起作用的原因是你以度为单位传递角度。 sincos三角函数需要以弧度表示的角度,因此数字应该从02*M_PI。对于d度,您通过M_PI*d/180.0M_PImath.h标题中定义的常量。

答案 4 :(得分:4)

我还需要这个来在代码中形成时钟指针的移动。我尝试了几种配方,但它们没有用,所以这就是我提出来的:

  • 动作 - 顺时针
  • 点 - 每6度(因为360度除以60度)是6度
  • 手长 - 65像素
  • center - 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是度数。

答案 5 :(得分:1)

这是c#实现。该方法将返回以radiuscenterangle 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);

答案 6 :(得分:1)

我想分享一下您的上述贡献如何帮助我制作了Arduino LCD指南针。我希望这是正确的礼节……我刚刚加入了stackoverflow,所以我要谢谢大家。

当站在上面的几何巨人的肩膀上时,我能够制作出此示例指南针: 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);

}

答案 7 :(得分:0)

答案恰恰相反。

X = Xc + rSin(角度)

Y = Yc + rCos(角度)

其中Xc和Yc是圆的中心坐标,r是半径。

答案 8 :(得分:0)

推荐:

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

答案 9 :(得分:-2)

您可以使用此:

圆方程

  

(x-k) 2 +(y-v) 2 = R 2

其中k和v为常数,R为半径