首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >始终从三点弧法返回CCW旋转

始终从三点弧法返回CCW旋转
EN

Stack Overflow用户
提问于 2016-02-08 18:27:29
回答 1查看 429关注 0票数 0

我正在尝试从一个表创建三点弧到autocad (R12/lt2) DXF文件中。问题是文件似乎总是在CCW旋转中保存弧。因此,如果我输入的pont数据是CCW,下面的方法工作正常,但是如果旋转是连续的,弧线的角度就会被“翻转”,我似乎找不出检测CW弧数据的方法来纠正错误。

该方法在圆弧的圆周上用3个点(而不是起始点、中心点和终点)来计算圆弧。

以下是我的方法:

代码语言:javascript
复制
public static List<double> threePointArch(double startX, double startY, double midX, double midY, double endX, double endY)
{
    List<double> returnValues = new List<double>();
    //Calculate center point from 3 points on a circle
    //calculate Line R
    double lineR = (midY - endY) / (midX - endX);
    //Calculate Line T
    double lineT = (startY - midY) / (startX - midX);
    //calculate x Center
    double centerX = ((lineR * lineT * (startY - endY)) + (lineR * (midX + startX)) - (lineT * (endX + midX))) / (2 * (lineR - lineT));
    //calculate y Center by subsitution
    double centerY = ((endY + midY) / 2) + ((centerX - ((endX + midX) / 2)) * (-1 / lineR));
    //Calculate Raduis
    double raduis = Math.Sqrt((startX - centerX) * (startX - centerX) + (startY - centerY) * (startY - centerY));

    //Calculate Start Angle
    double startAngle = Math.Atan2(startY - centerY, startX - centerX) * (180 / Math.PI);
    //Calculate End Angle
    double endtAngle = Math.Atan2(endY - centerY, endX - centerX) * (180 / Math.PI);

    //if (endtAngle < 0)
    //{
    //    endtAngle = endtAngle + 360;
    //}

    returnValues.Add(centerX);
    returnValues.Add(centerY);
    returnValues.Add(raduis);
    returnValues.Add(startAngle);
    returnValues.Add(endtAngle);
    return returnValues;
}

我已经尝试了三个星期了,每一次修复我都能想到,我试着计算中点角度,看看它是否小于端点角,我试着看看起始角是否小于端点角(有几个变化),这个数学是在我的头上!

编辑:

我发现了一些Here的信息,我想出了这个(添加在返回的后面):

代码语言:javascript
复制
  //calculate rotation
  double midAngle = Math.Atan2(midY - centerY, midX - centerX) * (180 / Math.PI);
  if (midAngle - startAngle > +180.0) midAngle -= 360.0;
  if (midAngle - startAngle < -180.0) midAngle += 360.0;
  if (endtAngle - midAngle > +180.0) endtAngle -= 360.0;
  if (endtAngle - midAngle < -180.0) endtAngle += 360.0;

  string dir = "none";
  if (midAngle - startAngle < 0)
      dir = "CW";
  if (midAngle - startAngle > 0)
      dir = "CCW";
  if (midAngle - startAngle == 0)
      dir = "none";

  if (dir == "CW")
  {
      double startAngletmp = startAngle;
      startAngle = endtAngle;
      endtAngle = startAngletmp;
  }

在大多数情况下,这似乎是可行的,但如果我能得到数学主管的证实,那就太好了。

EN

回答 1

Stack Overflow用户

发布于 2016-03-03 10:00:56

我假设这是2D的,所以使用交叉乘积来检测CW/CCW

p0,p1,p2作为你的弧形点作为三维向量,然后(x,y,z=0.0)

代码语言:javascript
复制
v0=p1-p0
v1=p2-p1

是边缘向量。现在计算交叉积

代码语言:javascript
复制
n=cross(v0,v1)

返回平面的法向量n你的弧线现在只需要测试它的z坐标的符号:

代码语言:javascript
复制
if (n.z<0.0) CW else CCW

该符号取决于您的坐标系的配置,因此如果它不能工作,请使用

代码语言:javascript
复制
if (n.z>0.0) CW else CCW

如果是(n.z==0.0),那么你就有麻烦了,不惜一切代价避免这种情况,把这些实体划分为2弧形。

还请参见arc via 3 points in specific direction

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35276659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档