设为首页收藏本站

中国膜结构网

 找回密码
 立即注册
膜结构车棚
膜结构车棚膜结构资质国产膜材 膜结构网中国膜结构协会
查看: 18|回复: 2

三点求圆弧中心arx

[复制链接]
  • TA的每日心情
    开心
    2021-3-7 10:01
  • 签到天数: 1440 天

    连续签到: 19 天

    [LV.10]以坛为家III

    发表于 2021-2-21 08:08 | 显示全部楼层 |阅读模式
    http://www.mjgw.org/ 专业从事膜结构设计、制作加工、施工安装的膜结构咨询服务,能够为客户提供专业的膜结构整体解决方案。做中国最好的膜结构综合服务平台。欢迎大家联系QQ:463017170.


    1. 已知空间三个点,解算外接圆圆心坐标,C++编程实现
    2. struct PT3
    3. {
    4.         double x, y, z;
    5. };

    6. int solveCenterPointOfCircle(std::vector<PT3> pd, double centerpoint[])
    7. {
    8.         double a1, b1, c1, d1;
    9.         double a2, b2, c2, d2;
    10.         double a3, b3, c3, d3;

    11.         double x1 = pd[0].x, y1 = pd[0].y, z1 = pd[0].z;
    12.         double x2 = pd[1].x, y2 = pd[1].y, z2 = pd[1].z;
    13.         double x3 = pd[2].x, y3 = pd[2].y, z3 = pd[2].z;

    14.         a1 = (y1*z2 - y2*z1 - y1*z3 + y3*z1 + y2*z3 - y3*z2);
    15.         b1 = -(x1*z2 - x2*z1 - x1*z3 + x3*z1 + x2*z3 - x3*z2);
    16.         c1 = (x1*y2 - x2*y1 - x1*y3 + x3*y1 + x2*y3 - x3*y2);
    17.         d1 = -(x1*y2*z3 - x1*y3*z2 - x2*y1*z3 + x2*y3*z1 + x3*y1*z2 - x3*y2*z1);

    18.         a2 = 2 * (x2 - x1);
    19.         b2 = 2 * (y2 - y1);
    20.         c2 = 2 * (z2 - z1);
    21.         d2 = x1 * x1 + y1 * y1 + z1 * z1 - x2 * x2 - y2 * y2 - z2 * z2;

    22.         a3 = 2 * (x3 - x1);
    23.         b3 = 2 * (y3 - y1);
    24.         c3 = 2 * (z3 - z1);
    25.         d3 = x1 * x1 + y1 * y1 + z1 * z1 - x3 * x3 - y3 * y3 - z3 * z3;

    26.         centerpoint[0] = -(b1*c2*d3 - b1*c3*d2 - b2*c1*d3 + b2*c3*d1 + b3*c1*d2 - b3*c2*d1)
    27.                 /(a1*b2*c3 - a1*b3*c2 - a2*b1*c3 + a2*b3*c1 + a3*b1*c2 - a3*b2*c1);
    28.         centerpoint[1] =  (a1*c2*d3 - a1*c3*d2 - a2*c1*d3 + a2*c3*d1 + a3*c1*d2 - a3*c2*d1)
    29.                 /(a1*b2*c3 - a1*b3*c2 - a2*b1*c3 + a2*b3*c1 + a3*b1*c2 - a3*b2*c1);
    30.         centerpoint[2] = -(a1*b2*d3 - a1*b3*d2 - a2*b1*d3 + a2*b3*d1 + a3*b1*d2 - a3*b2*d1)
    31.         centerpoint[2] = -(a1*b2*d3 - a1*b3*d2 - a2*b1*d3 + a2*b3*d1 + a3*b1*d2 - a3*b2*d1)
    32.                 /(a1*b2*c3 - a1*b3*c2 - a2*b1*c3 + a2*b3*c1 + a3*b1*c2 - a3*b2*c1);

    33.         return 0;
    34. }



    复制代码
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-3-7 10:01
  • 签到天数: 1440 天

    连续签到: 19 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-21 08:43 | 显示全部楼层
    1. 根据三点创建圆弧


    2. private Point3d GetArcCenter(Point3d pt1,Point3d pt2,Point3d pt3,ref double radius)
    3.         {
    4.             double xysm, xyse, xy;
    5.             double[] m_ArcCenter = new double[3];
    6.             xy = Math.Pow(pt1.X, 2) + Math.Pow(pt1.Y, 2);
    7.             xyse = xy - Math.Pow(pt3.X, 2) - Math.Pow(pt3.Y, 2);
    8.             xysm = xy - Math.Pow(pt2.X, 2) - Math.Pow(pt2.Y, 2);
    9.             xy = (pt1.X - pt2.X) * (pt1.Y - pt3.Y) - (pt1.X - pt3.X) * (pt1.Y - pt2.Y);
    10.             // 判断参数有效性
    11.             if (Math.Abs(xy)<0.000001)
    12.             {
    13.                 MessageBox.Show("所输入的参数无法创建圆形!");
    14.                 return Point3d.Origin;
    15.             }

    16.             // 获得圆心和半径
    17.             m_ArcCenter[0] = ((xysm * (pt1.Y - pt3.Y)) - (xyse * (pt1.Y - pt2.Y))) / (2 * xy);
    18.             m_ArcCenter[1] = ((xyse * (pt1.X - pt2.X)) - (xysm * (pt1.X - pt3.X))) / (2 * xy);
    19.             m_ArcCenter[2] = 0;
    20.             radius = Math.Sqrt((pt1.X - m_ArcCenter[0]) * (pt1.X - m_ArcCenter[0]) + (pt1.Y - m_ArcCenter[1]) * (pt1.Y - m_ArcCenter[1]));
    21.             if (radius<0.000001)
    22.             {
    23.                 MessageBox.Show("半径过小");
    24.                 return Point3d.Origin;
    25.             }

    26.             // 函数返回圆心的位置,而半径在参数中通过引用方式返回
    27.             Point3d arcCenter = new Point3d(m_ArcCenter[0], m_ArcCenter[1], m_ArcCenter[2]);
    28.             return arcCenter;
    29.         }

    30.         public Arc AddArcFromPt(Point3d ptSt,Point3d ptSc,Point3d ptEn,ObjectId objid,string featurename)
    31.         {
    32.             // 三点法创建圆弧
    33.             Point3d ptCenter;
    34.             double radius = 0.0;
    35.             Arc objArc;
    36.             ptCenter = GetArcCenter(ptSt, ptSc, ptEn, ref radius);
    37.             if (isClockWise(ptCenter, ptSt, ptSc, ptEn))
    38.                 objArc = AddArcCSEP(ptCenter, ptSt, ptEn, radius,objid,featurename);
    39.             else
    40.                 objArc = AddArcCSEP(ptCenter, ptEn, ptSt, radius,objid,featurename);
    41.             return objArc;
    42.         }

    43.         private Arc AddArcCSEP(Point3d ptCenter,Point3d ptSt,Point3d ptEn,double radius,ObjectId objid,string featurename)
    44.         {
    45.             double radiusent;
    46.             double stAng, enAng;
    47.             // 计算半径
    48.             radiusent = radius;
    49.             // 计算起点角度和终点角度
    50.             stAng = CalLineAngle(ptCenter, ptSt);
    51.             enAng = CalLineAngle(ptCenter, ptEn);
    52.             Arc objArc = new Arc(ptCenter, radius, stAng, enAng);
    53.             objArc.LinetypeId = objid;
    54.             objArc.Layer = featurename;
    55.             objArc.SetDatabaseDefaults();
    56.             return objArc;
    57.         }

    58.         private bool isClockWise(Point3d ptCenter,Point3d ptSt,Point3d ptSc,Point3d ptEn)
    59.         {
    60.             double a1, a2, a3;
    61.             a1 = CalLineAngle(ptSt, ptCenter);
    62.             a2 = CalLineAngle(ptSc, ptCenter);
    63.             a3 = CalLineAngle(ptEn, ptCenter);
    64.             bool isClock = (a1 < a2) | (a2 < a3) | (a1 < a3);
    65.             return isClock;
    66.         }

    67.         private double CalLineAngle(Point3d vStartPt,Point3d vEndPt)
    68.         {
    69.             double X, Y;
    70.             double CalculateLineAngle = 0.0;
    71.             double dbJudgeAngle = 0.001;
    72.             X = vEndPt.X - vStartPt.X;
    73.             Y = vEndPt.Y - vStartPt.Y;
    74.             if ((X > 0 && Y > 0)||(X > 0 && Y < 0))
    75.             {
    76.                 CalculateLineAngle = Math.Atan(Y / X);
    77.             }
    78.             else if ((X < 0 && Y > 0) || (X < 0 && Y < 0))
    79.             {
    80.                 CalculateLineAngle = Math.PI + Math.Atan(Y / X);
    81.             }
    82.             else if(X == 0)
    83.             {
    84.                 if (Y < 0)
    85.                 {
    86.                     CalculateLineAngle = -Math.PI / 2;
    87.                 }
    88.                 else if (Y > 0)
    89.                 {
    90.                     CalculateLineAngle = Math.PI / 2;
    91.                 }
    92.             }
    93.             else if (Y == 0)
    94.             {
    95.                 if (X < 0)
    96.                 {
    97.                     CalculateLineAngle = Math.PI;
    98.                 }
    99.                 else if (X > 0)
    100.                 {
    101.                     CalculateLineAngle = 0;
    102.                 }
    103.             }
    104.             else
    105.             {
    106.                 ;
    107.             }

    108.             if (Math.Abs(CalculateLineAngle - 0) < dbJudgeAngle)
    109.             {
    110.                 CalculateLineAngle = 0;
    111.                 return CalculateLineAngle;
    112.             }
    113.             else if (CalculateLineAngle < 0)
    114.             {
    115.                 CalculateLineAngle = 2 * Math.PI + CalculateLineAngle;
    116.                 return CalculateLineAngle;
    117.             }
    118.             else
    119.                 return CalculateLineAngle;
    120.         }

    121. #autoca
    复制代码
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-3-7 10:01
  • 签到天数: 1440 天

    连续签到: 19 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-21 08:43 | 显示全部楼层
    已知圆弧的一些信息,求得圆弧上中间点的坐标的方法(C++语言描述)
    1. // 从圆弧一些信息得到圆弧上一个特殊的点(计算的是二维图形的情况)
    2. Point3d DBOPERATION::GetArcTangencyPoint(Point3d pStartPoint, Point3d pEndPoint,
    3.                                          Point3d pCenterPoint,  double  dRadius,
    4.                                           double  dStartAngle,  double  dSweepAngle)
    5. {
    6.     Point3d pResultPoint;
    7.     pResultPoint.X  =   0 ;
    8.     pResultPoint.Y  =   0 ;
    9.     pResultPoint.Z  =   0 ;

    10.      // 因为会得到两个点,哪个点在弧上需要再进行判断
    11.      double  dRx1  =   0 ;
    12.      double  dRx2  =   0 ;
    13.      double  dRy1  =   0 ;
    14.      double  dRy2  =   0 ;

    15.      const   double  PI  =   3.1415926535897932 ;

    16.     Point3d pMiddlePoint;
    17.     pMiddlePoint.X  =  (pStartPoint.X  +  pEndPoint.X)  /   2 ;
    18.     pMiddlePoint.Y  =  (pStartPoint.Y  +  pEndPoint.Y)  /   2 ;
    19.     pMiddlePoint.Z  =   0.0 ;

    20.      // 扫角的角度值
    21.      double  dArcSweepAngle  =   180   *  dSweepAngle  /  PI;
    22.      // 中点到圆心的距离
    23.      double  ddy  =   0 ;
    24.      double  ddx  =   0 ;
    25.      if  (pMiddlePoint.X  -  pCenterPoint.X  >=   0.1e-6 )
    26.     {
    27.         ddx  =  pMiddlePoint.X  -  pCenterPoint.X;
    28.     }
    29.      if  (pMiddlePoint.Y  -  pCenterPoint.Y  >=   0.1e-6 )
    30.     {
    31.         ddx  =  pMiddlePoint.Y  -  pCenterPoint.Y;
    32.     }
    33.      double  dDistance  =  sqrt(ddx  *  ddx  +  ddy  *  ddy);

    34.      if  ((fabs(pMiddlePoint.Y  -  pCenterPoint.Y)  <   0.1e-6
    35.          &&  fabs(pMiddlePoint.X  -  pCenterPoint.X)  <   0.1e-6 )
    36.          &&  (fabs(pStartPoint.X  -  pEndPoint.X)  <   0.1e-6
    37.          ||  fabs(pStartPoint.Y  -  pEndPoint.Y)  < 0.1e-6  ))
    38.     {
    39.          // 半圆且斜率=0或者斜率为无穷大的情况
    40.          if  (fabs(pStartPoint.X  -  pEndPoint.X)  <   0.1e-6 )
    41.         {
    42.              // 结果的两个X的值
    43.             dRx1  =  pMiddlePoint.X  +  (dRadius  -  dDistance);
    44.             dRx2  =  pMiddlePoint.X  -  (dRadius  +  dDistance);
    45.              // 对应的两个Y的值
    46.             dRy1  =  pMiddlePoint.Y;
    47.             dRy2  =  pMiddlePoint.Y;
    48.         }
    49.          if  (fabs(pStartPoint.Y  -  pEndPoint.Y)  < 0.1e-6 )
    50.         {
    51.              // 结果的两个X的值
    52.             dRx1  =  pMiddlePoint.X;
    53.             dRx2  =  pMiddlePoint.X;
    54.              // 对应的两个Y的值
    55.             dRy1  =  pMiddlePoint.Y  +  (dRadius  -  dDistance);
    56.             dRy2  =  pMiddlePoint.Y  -  (dRadius  +  dDistance);
    57.         }
    58.     }
    59.      else   if  (fabs(pMiddlePoint.Y  -  pCenterPoint.Y)  <   0.1e-6
    60.          &&  fabs(pMiddlePoint.X  -  pCenterPoint.X)  >=   0.1e-6 )
    61.     {
    62.          // 圆心与端点中心点在水平线上的情况,斜率=0
    63.          // 结果的两个X的值
    64.         dRx1  =  pMiddlePoint.X  +  (dRadius  -  dDistance);
    65.         dRx2  =  pMiddlePoint.X  -  (dRadius  +  dDistance);
    66.          // 对应的两个Y的值
    67.         dRy1  =  pMiddlePoint.Y;
    68.         dRy2  =  pMiddlePoint.Y;
    69.     }
    70.      else   if  (fabs(pMiddlePoint.X  -  pCenterPoint.X)  <   0.1e-6
    71.          &&  fabs(pMiddlePoint.Y  -  pCenterPoint.Y)  >=   0.1e-6 )
    72.     {
    73.          // 圆心与端点中心点在垂直线上的情况,斜率=无穷大
    74.          // 结果的两个X的值
    75.         dRx1  =  pMiddlePoint.X;
    76.         dRx2  =  pMiddlePoint.X;
    77.          // 对应的两个Y的值
    78.         dRy1  =  pMiddlePoint.Y  +  (dRadius  -  dDistance);
    79.         dRy2  =  pMiddlePoint.Y  -  (dRadius  +  dDistance);
    80.     }
    81.      else
    82.     {
    83.          // 圆弧两个端点成线的斜率,已经排除了等于0或者无穷大的可能性
    84.          double  dTheKSAE  =  (pEndPoint.Y  -  pStartPoint.Y)  /  (pEndPoint.X  -  pStartPoint.X);
    85.          // 与端点组成的线垂直的线的斜率(0度,180度,360度弧的dk需要特殊处理)
    86.          double  dK  =  ( 1   /  dTheKSAE)  *  ( - 1 );

    87.          if  (fabs(fabs(dArcSweepAngle)  -   360 )  <   0.1e-6 )
    88.         {
    89.             dK  =  (pMiddlePoint.Y  -  pCenterPoint.Y)  /  (pMiddlePoint.X  -  pCenterPoint.X);
    90.         }
    91.          if  (fabs(fabs(dArcSweepAngle)  -   180 )  <   0.1e-6 )
    92.         {
    93.             dK  =  (pStartPoint.Y  -  pCenterPoint.Y)  /  (pStartPoint.X  -  pCenterPoint.X);
    94.             dK  =  ( 1   /  dK)  *  ( - 1 );
    95.         }
    96.          if  (fabs(fabs(dArcSweepAngle)  -   0 )  <   0.1e-6 )
    97.         {
    98.             dK  =  (pMiddlePoint.Y  -  pCenterPoint.Y)  /  (pMiddlePoint.X  -  pCenterPoint.X);
    99.         }
    100.          /
    101.          // 这是经过两端点中点并与两端点组成的直线垂直的直线的方程
    102.          // k为斜率,M(x),M(y)分别为中心点坐标值
    103.          // y=k * x - k * M(x) + M(y)
    104.          /

    105.          // 求出- k * M(x) + M(y)部分的值
    106.          double  dDif  =  ( - 1 )  *  dK  *  pMiddlePoint.X  +  pMiddlePoint.Y;

    107.          /
    108.          //  [x - C(x)]^2 + [y - C(y)]^2 = r^2
    109.          //  代入上面的y,其中- k * M(x) + M(y)以dDif代替
    110.          //  [x - C(x)]^2 + [kx + dDif - C(y)]^2 = r^2
    111.          //  下面以dBetween代替+ dDif - C(y)
    112.          /
    113.          double  dBetween  =  dDif  -  pCenterPoint.Y;

    114.          /
    115.          //  x^2 + 2*C(x)*x + [C(x)]^2
    116.          //  +
    117.          //  (kx)^2 + 2*k*dBetween*x + (dBetween)^2
    118.          //  = r^2
    119.          /

    120.          // 再求中间值
    121.          double  dNx  =  ( 2   *  dK  *  dBetween  -   2   *  pCenterPoint.X)  /  ( 1   +  dK  *  dK);
    122.          double  dLa  =  (dRadius  *  dRadius  -  pCenterPoint.X  *  pCenterPoint.X
    123.              -  dBetween  *  dBetween)  /  ( 1   +  dK  *  dK);
    124.          double  dAd  =  dLa  +  dNx  *  dNx  /   4 ;

    125.          // 结果的两个X的值
    126.         dRx1  =  sqrt(dAd)  -  dNx  /   2 ;
    127.         dRx2  =  ( - 1 )  *  sqrt(dAd)  -  dNx  /   2 ;
    128.          // 对应的两个Y的值
    129.         dRy1  =  dK  *  dRx1  -  dK  *  pMiddlePoint.X  +  pMiddlePoint.Y;
    130.         dRy2  =  dK  *  dRx2  -  dK  *  pMiddlePoint.X  +  pMiddlePoint.Y;
    131.     }

    132.      // 对得到的两个点进行判断,找到在弧上的那个
    133.     pResultPoint.X  =  dRx1;
    134.     pResultPoint.Y  =  dRy1;
    135.      if  (fabs(fabs(dArcSweepAngle)  -   180.0 )  <   0.1e-4 )
    136.     {
    137.          // 半圆情况处理
    138.          double  p1x,p1y,p2x,p2y,qx,qy,dx1,dy1,dx2,dy2,det;
    139.         p2x  =  pStartPoint.X;
    140.         p2y  =  pStartPoint.Y;
    141.         p1x  =  pCenterPoint.X;
    142.         p1y  =  pCenterPoint.Y;
    143.         qx  =  dRx2;
    144.         qy  =  dRy2;

    145.         dx1  =  p2x  -  p1x;
    146.         dy1  =  p2y  -  p1y;
    147.         dx2  =  qx -  p2x;
    148.         dy2  =  qy  -  p2y;
    149.         det  =  dx1 * dy2  -  dx2 * dy1;
    150.         BOOL bBlockWise  =  TRUE;
    151.          if  (det  >   0.0 )
    152.         {
    153.              // 逆时针方向
    154.             bBlockWise  =  FALSE;
    155.         }
    156.          if  ((( ! bBlockWise)  &&  (dArcSweepAngle  >   0.0 ))
    157.              ||  ((bBlockWise)  &&  (dArcSweepAngle  <   0.0 )))
    158.         {
    159.             pResultPoint.X  =  dRx2;
    160.             pResultPoint.Y  =  dRy2;
    161.         }
    162.     }
    163.      else
    164.     {
    165.          // 非半圆的情况
    166.          double  dd1  =  sqrt(pow(dRx1  -  pMiddlePoint.X,  2 )
    167.              +  pow(dRy1  -  pMiddlePoint.Y,  2 ));
    168.          double  dd2  =  sqrt(pow(dRx2  -  pMiddlePoint.X,  2 )
    169.              +  pow(dRy2  -  pMiddlePoint.Y,  2 ));
    170.          if  (((dd1  <  dd2)  &&  (fabs(dArcSweepAngle)  >   180.0 ))
    171.              ||  ((dd1  >  dd2)  &&  (fabs(dArcSweepAngle)  <   180.0 )))
    172.         {
    173.             pResultPoint.X  =  dRx2;
    174.             pResultPoint.Y  =  dRy2;
    175.         }
    176.     }

    177.      return  pResultPoint;
    178. }
    复制代码
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    推荐膜材品牌上一条 /5 下一条

    进口膜材 国产膜材 pvdf膜材ptfe膜材ETFE膜材
    最好的膜结构公司 一级膜结构资质 膜结构一级资质
    膜结构设计-膜结构十大品牌-etfe设计-充气膜结构
    诺科膜结构
    遨都膜结构设计
    中国膜结构网
    中国空间膜结构协会

    QQ|申请友链|Archiver|手机版|中国膜结构论坛

    GMT+8, 2021-3-8 01:40 , Processed in 0.284918 second(s), 22 queries .

    Powered by 中国膜结构网->膜材采购->膜结构设计->膜结构安装->膜结构维修

    © 2014-2020 膜结构协会->进口膜材->国产膜材->PVDF膜材->PTFE膜材->ETFE膜材.

    快速回复 返回顶部 返回列表