【问题标题】:Calculating point on a circle's circumference from angle in C#?在C#中从角度计算圆的圆周上的点?
【发布时间】:2009-03-23 16:57:06
【问题描述】:

我想这是一个简单的问题,但我当前的代码得到了一些奇怪的结果,而且我没有数学背景来完全理解原因。我的目标很简单,如标题所述:我只想找到与中心点有一定距离和角度的点。

我当前的代码:

Point centerPoint = new Point ( 0, 0 );
Point result      = new Point ( 0, 0 );
double angle      = 0.5; //between 0 and 2 * PI, angle is in radians
int distance      = 1000;

result.Y = centerPoint.Y + (int)Math.Round( distance * Math.Sin( angle ) );
result.X = centerPoint.X + (int)Math.Round( distance * Math.Cos( angle ) );

一般来说,这似乎相当合理,但我在不同的地方遇到了问题,最明显的是当角度对应于负 x 和 y 轴上的点时。很明显我做错了什么——想想那是什么?

更新:这是我的错误,这段代码工作正常——少数不工作的异常值实际上是由于计算 1.5PI 的角度存在错误。我以为我已经检查得足够好,但显然没有。感谢大家的时间,希望上面的工作代码对其他人有帮助。

【问题讨论】:

  • 你的意思是“我在不同的地方遇到问题”?
  • 是否故意不使用 centerPoint?不应该将 centerPoint.X 和 .Y 添加到结果中吗?
  • 你能提供一个问题的例子吗?
  • 在你描述你的结果究竟出了什么问题之前,我不认为你会得到更多的结果。
  • 请不要将距离称为 X,将角度称为 Y。这是违反直觉的。距离是你的半径,角度是你的……角度。

标签: c# math geometry angle


【解决方案1】:

您忘记添加中心点:

result.Y = (int)Math.Round( centerPoint.Y + distance * Math.Sin( angle ) );
result.X = (int)Math.Round( centerPoint.X + distance * Math.Cos( angle ) );

其余的应该没问题...(你得到了什么奇怪的结果?你能给出准确的输入吗?)

【讨论】:

  • 啊,这是关于中心点的一个好点——在这种情况下它没有被使用。我目前正在使用的特定点是中心点 0,0,因此在这种情况下它是无关紧要的,但在其他情况下它肯定会有所作为。我已更新示例以正确包含它。
【解决方案2】:

首先,由于您使用的是弧度,因此这样定义您的角度可能是有益的:

double angle = (Math.PI / 3); // 60 degrees...

函数本身运行良好。如果您的距离足够小,四舍五入只会影响您的答案。除此之外,答案应该很好。

如果您担心的是四舍五入,请记住,默认情况下,.NET 执行banker's rounding,您可能想要:

result.X = (int)Math.Round(centerPoint.X + distance * Math.Cos(angle), MidpointRounding.AwayFromZero);
result.Y = (int)Math.Round(centerPoint.Y + distance * Math.Sin(angle), MidpointRounding.AwayFromZero);

改为。

另外,在你想要距离X和角度Y的问题中......我假设你没有将它与(X,Y)点联系起来,因为那是完全不同的。

距离公式为:

double distance = Math.Sqrt((centerPoint.X + result.X)^2 + (centerPoint.Y + result.Y)^2);

【讨论】:

  • 约翰,谢谢你的鱼。我很高兴地没有意识到 C# 完全舍入了双重计算,更不用说非常糟糕了(恕我直言)。
【解决方案3】:

Swift3 版本

func pointOnCircle(radius: Double, angleInDegrees: Double, origin: CGPoint) -> CGPoint {
    let x = abs(Double(origin.x) + radius * cos(angleInDegrees * (.pi / 180)))
    let y = abs(Double(origin.y) - radius * sin(angleInDegrees * (.pi / 180)))

    return CGPoint(x: x, y: y)
}

【讨论】:

    【解决方案4】:

    如果没有关于确切错误的更多信息,就很难判断出了什么问题。方程看起来正确,应该可以工作。您确定您传入的角度对于 > 90 度的角度是否正确?我唯一能想到的另一件事是您将距离(一个 int)乘以 Math.sin(双精度)的结果,但这应该不是问题。

    【讨论】:

      【解决方案5】:
      -(NSMutableArray *)GetPointsForCircle
          {
             NSMutableArray *Points = [[NSMutableArray alloc] init];
             CGPoint CenterPoint = CGPointMake(160, 230);
             CGPoint Point;
             for (float Angel = 0; Angel <= 360; Angel+= 60)
               {
                 Point.x = CenterPoint.x + 100 * cos(Angel);
                 Point.y = CenterPoint.y + 100 * sin(Angel);
                 [Points addObject:[NSValue valueWithCGPoint:Point]];
               }
             return Points;
          }
      
          - (CGPoint)pointOnCircle:(int)thisPoint withTotalPointCount:(int)totalPoints
           {
              CGPoint centerPoint = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
              float radius = 100.0;
              float angle = ( 2 * M_PI / (float)totalPoints ) * (float)thisPoint;
              CGPoint newPoint;
              newPoint.x = (centerPoint.x) + (radius * cosf(angle));
              newPoint.y = (centerPoint.y) + (radius * sinf(angle));
              return newPoint;   
          }
      

      【讨论】:

      • 为半径为 100 的圆返回 6 个点。圆的参数方程为 x = cx + r * cos(a) y = cy + r * sin(a) 其中 r 是半径, cx,cy 原点和角度 0..2PI 弧度或 0..360 度。
      【解决方案6】:

      我不知道 c#,无论如何,如果你想在某个地方绘制点,你必须考虑 Y 轴从屏幕顶部到底部折痕的事实,所以你的 sin 元素应该是 -sin(...) 而不是 +sin(...)

      所以

      result.Y = centerPoint.Y + (int)Math.Round( distance * Math.Sin( angle ) );
      

      应该变成:

      result.Y = centerPoint.Y - (int)Math.Round( distance * Math.Sin( angle ) );
      

      如果您不尝试绘制它们,我无法想象问题是什么,您能举个例子吗?

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多