• 异面直线公垂线的垂足坐标计算公式推导(二)


        根据异面直线公垂线的垂足坐标计算公式,定义逻辑类,计算垂足的坐标值。用C#定义该逻辑类,如下

        /// <summary>
        ///公垂线垂足坐标通用推导公式
        /// </summary>
        public class CommonPerpendicular
        {
            //AB构成的直线
            private IPoint ptA = null;
            private IPoint ptB = null;

            //AB直线上的垂足
            private IPoint ptM = null;

            //CD构成的直线
            private IPoint ptC = null;
            private IPoint ptD = null;

            //CD直线上的垂足
            private IPoint ptN = null;

            public CommonPerpendicular()
            {
                try
                {
                }
                catch (Exception ex)
                {
                    if (AppLog.log.IsErrorEnabled)
                        AppLog.log.Error("PipeProjFactory:" + ex.Message);
                }
            }

            /// <summary>
            /// 计算异面直线的公垂线两个垂足的坐标
            /// </summary>
            /// <param name="A"></param>
            /// <param name="B"></param>
            /// <param name="C"></param>
            /// <param name="D"></param>
            /// <param name="M">AB直线上的垂足坐标M</param>
            /// <param name="N">CD直线上的垂足坐标N</param>
            /// <returns></returns>
            public bool ComputePerpendicular(IPoint A, IPoint B, IPoint C, IPoint D, IPoint M, IPoint N)
            {
                try
                {
                    if (null == A || null == B || null == C || null == D || null == M || null == N)
                    {
                        return false;
                    }

                    ptA = A;
                    ptB = B;

                    ptC = C;
                    ptD = D;

                    ptM = M;
                    ptN = N;

                    //f1ab
                    double fSquareAB = FunSquare(ptA, ptB);

                    if (-99999999.99999 == fSquareAB)
                    {
                        return false;

                    }

                    //f1cd
                    double fSquareCD = FunSquare(ptC, ptD);

                    if (-99999999.99999 == fSquareCD)
                    {
                        return false;

                    }

                    //f3ab
                    double fVaryAB = FunVaryOperation(ptA, ptB);
                    if (-99999999.99999 == fVaryAB)
                    {
                        return false;

                    }

                    //f3cd
                    double fVaryCD = FunVaryOperation(ptC, ptD);
                    if (-99999999.99999 == fVaryCD)
                    {
                        return false;

                    }

                    //f2
                    double fCross = FunCrossOperation();
                    if (-99999999.99999 == fCross)
                    {
                        return false;

                    }

                    double t1 = (fVaryAB * fSquareCD - fVaryCD * fCross) / (fSquareAB * fSquareCD - fCross * fCross);

                    double t2 = (fVaryCD * fSquareAB - fCross * fVaryAB) / (fCross * fCross - fSquareAB * fSquareCD);

                    ptM.X = t1 * (ptB.X - ptA.X) + ptA.X;
                    ptM.Y = t1 * (ptB.Y - ptA.Y) + ptA.Y;
                    ptM.Z = t1 * (ptB.Z - ptA.Z) + ptA.Z;

                    ptN.X = t2 * (ptD.X - ptC.X) + ptC.X;
                    ptN.Y = t2 * (ptD.Y - ptC.Y) + ptC.Y;
                    ptN.Z = t2 * (ptD.Z - ptC.Z) + ptC.Z;

                    return true;
                }
                catch (Exception ex)
                {
                    if (AppLog.log.IsErrorEnabled)
                        AppLog.log.Error("PipeProjFactory:" + ex.Message);
                    return false;
                }
            }

            /// <summary>
            /// [(xb-xa)*(xb-xa)+(yb-ya)*(yb-ya)+(zb-za)*(zb-za)],两个点可以被替换
            /// </summary>
            /// <param name="P1"></param>
            /// <param name="P2"></param>
            /// <returns></returns>
            private double FunSquare(IPoint P1, IPoint P2)
            {
                try
                {
                    double funValue = 0.0;

                    funValue = Math.Sqrt(P2.X - P1.X) + Math.Sqrt(P2.Y - P1.Y) + Math.Sqrt(P2.Z - P1.Z);

                    return funValue;

                }
                catch (Exception ex)
                {
                    if (AppLog.log.IsErrorEnabled)
                        AppLog.log.Error("PipeProjFactory:" + ex.Message);
                    return -99999999.99999;
                }
            }

           /// <summary>
           /// (xb-xa)*(xc-xa)+(yb-ya)*(yc-ya)+(zb-za)*(zc-za),每个和项的第一个公式可以被替换
           /// </summary>
           /// <param name="P1"></param>
           /// <param name="P2"></param>
           /// <returns></returns>
            private double FunVaryOperation(IPoint P1,IPoint P2)
            {
                try
                {
                    double funValue = 0.0;

                    funValue = (P2.X-P1.X)*(ptC.X -ptA.X)+(P2.Y-P1.Y)*(ptC.Y-ptA.Y)+(P2.Z-P1.Z)*(ptC.Z-ptA.Z);

                    return funValue;
                }
                catch (Exception ex)
                {
                    if (AppLog.log.IsErrorEnabled)
                        AppLog.log.Error("PipeProjFactory:" + ex.Message);
                    return -99999999.99999;
                }
            }

            /// <summary>
            /// (xb-xa)*(xd-xc)+(yb-ya)*(yd-yc)+(zb-za)*(zd-zc)
            /// </summary>
            /// <returns></returns>
            private double FunCrossOperation()
            {
                try
                {
                    double funValue = 0.0;

                    funValue = (ptB.X - ptA.X) * (ptD.X - ptC.X) + (ptB.Y - ptA.Y) * (ptD.Y - ptC.Y) + (ptB.Z - ptA.Z) * (ptD.Z - ptC.Z);

                    return funValue;
                }
                catch (Exception ex)
                {
                    if (AppLog.log.IsErrorEnabled)
                        AppLog.log.Error("PipeProjFactory:" + ex.Message);
                    return -99999999.99999;
                }
            }
        }

        在逻辑函数定义中,已知P1和P2定义的直线,Q1和Q2定义的直线。判断这两个异面直线的公垂线垂足是否在各自线段范围内,即垂足PPNormalPoint是否在P1P2线段范围内,垂足QQNormalPoint是否在Q1Q2线段范围内。

             /// <summary>
            /// 计算公垂线的两个垂足,判断是否都在4个点确定的两条线段范围上
            /// </summary>
            /// <returns></returns>
            private bool GetNormalCoplanarPoints()
            {
                try
                {
                    IPoint PPNormalPoint = new PointClass();
                    IPoint QQNormalPoint = new PointClass();

                    CommonPerpendicular commonPerPoint = new CommonPerpendicular();

                    if (commonPerPoint.ComputePerpendicular(P1, P2, Q1, Q2, PPNormalPoint, QQNormalPoint))
                    {
                        if (IsPointInLine(PPNormalPoint, P1, P2) && IsPointInLine(QQNormalPoint, Q1, Q2))
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    if (AppLog.log.IsErrorEnabled)
                        AppLog.log.Error("CollisionAnalysis:" + ex.Message);
                    return false;
                }
            }

            /// <summary>
            /// 直线上一点是否在起终点确定线段上
            /// </summary>
            /// <param name="pNormal"></param>
            /// <param name="pStart"></param>
            /// <param name="pEnd"></param>
            /// <returns></returns>
            private bool IsPointInLine(IPoint pNormal, IPoint pStart, IPoint pEnd)
            {
                try
                {
                    if (null == pNormal || null == pStart || null == pEnd)
                    {
                        return false;
                    }

                    double x = pNormal.X;
                    double y = pNormal.Y;
                    double z = pNormal.Z;

                    double minx = pStart.X > pEnd.X ? pEnd.X : pStart.X;
                    double maxx = pStart.X > pEnd.X ? pStart.X : pEnd.X;
                    double miny = pStart.Y > pEnd.Y ? pEnd.Y : pStart.Y;
                    double maxy = pStart.Y > pEnd.Y ? pStart.Y : pEnd.Y;
                    double minz = pStart.Z > pEnd.Z ? pEnd.Z : pStart.Z;
                    double maxz = pStart.Z > pEnd.Z ? pStart.Z : pEnd.Z;

                    if ((x > minx && x < maxx) && (y > miny && y < maxy) && (z > minz && z < maxz))
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    if (AppLog.log.IsErrorEnabled)
                        AppLog.log.Error("CollisionAnalysis:" + ex.Message);
                    return false;
                }
            }

    QQ32663739,欢迎沟通交流。
  • 相关阅读:
    jQuery入门级part.2
    jQuery入门级part.1
    总结十二天
    延时器和定时器
    总结第十一天
    总结第十天
    总结第九天
    android特殊字符
    android 查看 当前activity
    京东运营 不错的帖子
  • 原文地址:https://www.cnblogs.com/chuzhouGIS/p/2286308.html
Copyright © 2020-2023  润新知