三维空间中,点与点,点与直线,点与面的距离,面积等相关运算,点是否在三角形内运算

public class Pvector {
    public double L=0,z=0;
    public double a=0,x=0;
    public double b=0,y=0;
    
    public double GetL(){return L;}
    public double GetZ(){return L;}
    public void SetL(double l){
        this.L=l;
        this.z=l;
    }
    public void SetZ(double z){
        this.L=z;
        this.z=z;
    }
    
    public double GetA(){return a;}
    public double GetX(){return a;}
    public void SetA(double a){
        this.a=a;
        this.x=a;
    }
    public void SetX(double x){
        this.a=x;
        this.x=x;
    }
    
    public double GetB(){return b;}
    public double GetY(){return b;}
    public void SetB(double b){
        this.b=b;
        this.y=b;
    }
    public void SetY(double y){
        this.b=y;
        this.y=y;
    }
}


    
    //三维空间中,求points点到pointa,pointb直线的距离
    public double DistanceOfPointToLine(Pvector pointa, Pvector pointb, Pvector pointS)
    {
        double ab = Math.sqrt(Math.pow((pointa.x - pointb.x), 2.0) + Math.pow((pointa.y - pointb.y), 2.0) + Math.pow((pointa.z - pointb.z), 2.0));
        double as = Math.sqrt(Math.pow((pointa.x - pointS.x), 2.0) + Math.pow((pointa.y - pointS.y), 2.0) + Math.pow((pointa.z - pointS.z), 2.0));
        double bs = Math.sqrt(Math.pow((pointS.x - pointb.x), 2.0) + Math.pow((pointS.y - pointb.y), 2.0) + Math.pow((pointS.z - pointb.z), 2.0));
        double cos_A = (Math.pow(as, 2.0) + Math.pow(ab, 2.0) - Math.pow(bs, 2.0)) / (2 * ab*as);
        double sin_A = Math.sqrt(1 - Math.pow(cos_A, 2.0));
        return as*sin_A;
    }
    
    //三维空间中,求points点到pointa,pointb直线的哪一边(或者哪个方向上)
    //0为点S在两点直线的里面,1位两点的B点方向上,-1位在A点方向上
    public int PoinInLineLeftOrRight(Pvector pointa, Pvector pointb, Pvector pointS){
        int value=0;
        double dlen_ab = Math.sqrt(Math.pow((pointa.x - pointb.x), 2.0) + Math.pow((pointa.y - pointb.y), 2.0) + Math.pow((pointa.z - pointb.z), 2.0));
        double dlen_as = Math.sqrt(Math.pow((pointa.x - pointS.x), 2.0) + Math.pow((pointa.y - pointS.y), 2.0) + Math.pow((pointa.z - pointS.z), 2.0));
        double dlen_bs = Math.sqrt(Math.pow((pointS.x - pointb.x), 2.0) + Math.pow((pointS.y - pointb.y), 2.0) + Math.pow((pointS.z - pointb.z), 2.0));
        if(dlen_as>dlen_bs){//1
            if(dlen_as>dlen_ab){
                value=1;
            }else{
                value=0;
            }
        }else{//-1
            if(dlen_bs>dlen_ab){
                value=-1;
            }else{
                value=0;
            }
        }
        return value;
    }
    
    ///三维空间中,据坐标值判断点在三角形内
    public boolean IsInTrigon3D(Pvector pointa, Pvector pointb, Pvector pointc, Pvector pointS){
        boolean value=false;
        double dlen_abs=DistanceOfPointToLine(pointa,pointb,pointS);
        double dlen_ab=PointToPointLenght(pointa.GetL(),pointa.GetA(),pointa.GetB(),pointb.GetL(),pointb.GetA(),pointb.GetB());
        double dS_abs=dlen_ab*dlen_abs/2;
        double dlen_acs=DistanceOfPointToLine(pointa,pointc,pointS);
        double dlen_ac=PointToPointLenght(pointa.GetL(),pointa.GetA(),pointa.GetB(),pointc.GetL(),pointc.GetA(),pointc.GetB());
        double dS_acs=dlen_ac*dlen_acs/2;
        double dlen_bcs=DistanceOfPointToLine(pointb,pointc,pointS);
        double dlen_bc=PointToPointLenght(pointb.GetL(),pointb.GetA(),pointb.GetB(),pointc.GetL(),pointc.GetA(),pointc.GetB());
        double dS_bcs=dlen_bc*dlen_bcs/2;
        
        double dlen_abc=DistanceOfPointToLine(pointa,pointb,pointc);
        double dS_abc=dlen_ab*dlen_abc/2;
        double dSub_S=(dS_abs+dS_acs+dS_bcs)-dS_abc;
        if(dSub_S<0.009){
            value=true;
        }
        return value;
    }
    
    //三维空间中,两点的距离计算函数
    public double PointToPointLenght(double one_Z, double one_X, double one_Y, double two_Z, double two_X, double two_Y) {
        double dtZ = one_Z - two_Z;
        double dtX = one_X - two_X;
        double dtY = one_Y - two_Y;
        double lenResult = Math.sqrt(dtZ * dtZ + dtX * dtX + dtY * dtY);
        return Double.parseDouble(String.format("%.4f", lenResult));            
    }

        //三维空间中,直线与平面的交点坐标计算函数
        public double[] MianXianJiaoDianXYZ(double Lx1, double Ly1, double Lz1, double Lx2, double Ly2, double Lz2, double Px1, double Py1, double Pz1, double Px2, double Py2, double Pz2, double Px3, double Py3, double Pz3)
        {
            double[] newJiaoPoint = new double[3];
            //L直线矢量
            double m = Lx2 - Lx1;
            double n = Ly2 - Ly1;
            double p = Lz2 - Lz1;
            //MessageBox.Show(m.ToString("#0.#") + "," + n.ToString("#0.#") + "," + p.ToString("#0.#,"));

            //平面方程Ax+BY+CZ+d=0 行列式计算
            double A = Py1 * Pz2 + Py2 * Pz3 + Py3 * Pz1 - Py1 * Pz3 - Py2 * Pz1 - Py3 * Pz2;
            double B = -(Px1 * Pz2 + Px2 * Pz3 + Px3 * Pz1 - Px3 * Pz2 - Px2 * Pz1 - Px1 * Pz3);
            double C = Px1 * Py2 + Px2 * Py3 + Px3 * Py1 - Px1 * Py3 - Px2 * Py1 - Px3 * Py2;
            double D = -(Px1 * Py2 * Pz3 + Px2 * Py3 * Pz1 + Px3 * Py1 * Pz2 - Px1 * Py3 * Pz2 - Px2 * Py1 * Pz3 - Px3 * Py2 * Pz1);
            //MessageBox.Show(A.ToString("#0.#") + "," + B.ToString("#0.#") + "," + C.ToString("#0.#,") + "," + D.ToString("#0.#,"));
            //系数比值 t=-(Axp+Byp+Cxp+D)/(A*m+B*n+C*p)

            if (A * m + B * n + C * p == 0)  //判断直线是否与平面平行   
            {
                newJiaoPoint = null;
            }
            else
            {
                double t = -(Lx1 * A + Ly1 * B + Lz1 * C + D) / (A * m + B * n + C * p);
                //MessageBox.Show(t.ToString("#0.##############"));
                newJiaoPoint[0] = Lx1 + m * t;
                newJiaoPoint[1] = Ly1 + n * t;
                newJiaoPoint[2] = Lz1 + p * t;
                //MessageBox.Show(newJiaoPoint[0].ToString("#0.####") + "," + newJiaoPoint[1].ToString("#0.####") + "," + newJiaoPoint[2].ToString("#0.####"));

            }
            return (newJiaoPoint);

            //公式参考   东北师范大学 空间解析几何p107
            //调用:
            //有交点情况下:
            //            double[] Point = new double[3];
            //            Point=JiaoDianZuoBiao(20, 20, 8, 30, 23.5, 6, 25, 27, 10, 25, 20, 10, 25, 20, 0);
            //            MessageBox.Show(Point[0].ToString("#0.####") + "," + Point[1].ToString("#0.####") + "," + Point[2].ToString("#0.####"));
            ////交点坐标计算为25,21.75,7
            //            Point = JiaoDianZuoBiao(1, 23, 19, 27, 14, 5, 0, 18, 8, 18, 5, 18, 25, 37, 4);
            //            MessageBox.Show(Point[0].ToString("#0.####") + "," + Point[1].ToString("#0.####") + "," + Point[2].ToString("#0.####"));
            ////交点坐标计算为15.4738,17.9898,11.2064

            /*
            已知三点坐标怎样求法向量?
            已知A(x1,y1,z1),B(x2,y2,z2),C(x3,y3,z3)三点的面怎样求它的法向量
            求:1.三个点可以形成3个向量,比如向量AB,向量AC和向量BC,则分别得到(x2-x1,y2-y1,z2-z1),AC(x3-x1,y3-y1,z3-z1),(x3-x2,y3-y2,z3-z2)
                2.设平面的法向量坐标是(x,y,z)则,根据法向量定义的,得到方程组:
                (x2-x1)*x+(y2-y1)*y+(z2-z1)*z=0;
                且(x3-x1)*x+(y3-y1)*y+(z3-z1)*z=0;
                且(x3-x2)*x+(y3-y2)*y+(z3-z2)*z=0 ;
                解出来x,y,z就是平面法向量的坐标,方向满足 右手螺旋 法则.
            */
        }

        //三维空间中,求points点到pointa,pointb直线的距离
        public double DistanceOfPointToLine(Pvector pointa, Pvector pointb, Pvector pointS)
    {
        double dab = Math.Sqrt(Math.Pow((pointa.x - pointb.x), 2.0) + Math.Pow((pointa.y - pointb.y), 2.0) + Math.Pow((pointa.z - pointb.z), 2.0));
        double das = Math.Sqrt(Math.Pow((pointa.x - pointS.x), 2.0) + Math.Pow((pointa.y - pointS.y), 2.0) + Math.Pow((pointa.z - pointS.z), 2.0));
        double dbs = Math.Sqrt(Math.Pow((pointS.x - pointb.x), 2.0) + Math.Pow((pointS.y - pointb.y), 2.0) + Math.Pow((pointS.z - pointb.z), 2.0));
        double dcos_A = (Math.Pow(das, 2.0) + Math.Pow(dab, 2.0) - Math.Pow(dbs, 2.0)) / (2 * dab*das);
        double dsin_A = Math.Sqrt(1 - Math.Pow(dcos_A, 2.0));
        return das*dsin_A;
    }

        //三维空间中,求points点到pointa,pointb直线的哪一边(或者哪个方向上)
        //0为点S在AB两点直线的里面,1为AB两点的B点方向上,-1为AB两点的A点方向上
        public int PoinInLineLeftOrRight(Pvector pointa, Pvector pointb, Pvector pointS)
        {
            int value = 0;
            double dlen_ab = Math.Sqrt(Math.Pow((pointa.x - pointb.x), 2.0) + Math.Pow((pointa.y - pointb.y), 2.0) + Math.Pow((pointa.z - pointb.z), 2.0));
            double dlen_as = Math.Sqrt(Math.Pow((pointa.x - pointS.x), 2.0) + Math.Pow((pointa.y - pointS.y), 2.0) + Math.Pow((pointa.z - pointS.z), 2.0));
            double dlen_bs = Math.Sqrt(Math.Pow((pointS.x - pointb.x), 2.0) + Math.Pow((pointS.y - pointb.y), 2.0) + Math.Pow((pointS.z - pointb.z), 2.0));
            if (dlen_as > dlen_bs)
            {//1
                if (dlen_as > dlen_ab)
                {
                    value = 1;
                }
                else
                {
                    value = 0;
                }
            }
            else
            {//-1
                if (dlen_bs > dlen_ab)
                {
                    value = -1;
                }
                else
                {
                    value = 0;
                }
            }
            return value;
        }

        ///三维空间中,据坐标值判断点在三角形内
        public bool IsInTrigon3D(Pvector pointa, Pvector pointb, Pvector pointc, Pvector pointS)
        {
            bool value = false;
            double dlen_abs = DistanceOfPointToLine(pointa, pointb, pointS);
            double dlen_ab = PointToPointLenght(pointa.GetL(), pointa.GetA(), pointa.GetB(), pointb.GetL(), pointb.GetA(), pointb.GetB());
            double dS_abs = dlen_ab * dlen_abs / 2;
            double dlen_acs = DistanceOfPointToLine(pointa, pointc, pointS);
            double dlen_ac = PointToPointLenght(pointa.GetL(), pointa.GetA(), pointa.GetB(), pointc.GetL(), pointc.GetA(), pointc.GetB());
            double dS_acs = dlen_ac * dlen_acs / 2;
            double dlen_bcs = DistanceOfPointToLine(pointb, pointc, pointS);
            double dlen_bc = PointToPointLenght(pointb.GetL(), pointb.GetA(), pointb.GetB(), pointc.GetL(), pointc.GetA(), pointc.GetB());
            double dS_bcs = dlen_bc * dlen_bcs / 2;

            double dlen_abc = DistanceOfPointToLine(pointa, pointb, pointc);
            double dS_abc = dlen_ab * dlen_abc / 2;
            double dSub_S = (dS_abs + dS_acs + dS_bcs) - dS_abc;
            if (dSub_S < 0.3)
            {
                value = true;
            }
            return value;
        }

        ///三维空间中,获取两条直线的最短距离
        public double GetLineLineDistance(Pvector pointa1, Pvector pointa2, Pvector pointb1, Pvector pointb2)
        {
            double value = 0;
            LineToLineComputeIn3D lineline = new LineToLineComputeIn3D();
            lineline.SetLineA(pointa1.GetX(), pointa1.GetY(), pointa1.GetZ(), pointa2.GetX(), pointa2.GetY(), pointa2.GetZ());
            lineline.SetLineB(pointb1.GetX(), pointb1.GetY(), pointb1.GetZ(), pointb2.GetX(), pointb2.GetY(), pointb2.GetZ());
            lineline.StartCompute();
            value = lineline.GetTwoLineDistance();
            return value;
        }

        ///三维空间中,获取两条直线的最短距离直线上的两点A、B
        public Pvector[] GetLineLineMinDistancePoints(Pvector pointa1, Pvector pointa2, Pvector pointb1, Pvector pointb2)
        {
            Pvector[] values = new Pvector[2];
            LineToLineComputeIn3D lineline = new LineToLineComputeIn3D();
            lineline.SetLineA(pointa1.GetX(), pointa1.GetY(), pointa1.GetZ(), pointa2.GetX(), pointa2.GetY(), pointa2.GetZ());
            lineline.SetLineB(pointb1.GetX(), pointb1.GetY(), pointb1.GetZ(), pointb2.GetX(), pointb2.GetY(), pointb2.GetZ());
            lineline.StartCompute();
            Pvector pvector1 = new Pvector();
            Pvector pvector2 = new Pvector();
            double[] pointa = lineline.GetThePointInLineA();
            double[] pointb = lineline.GetThePointInLineB();
            pvector1.SetL(pointa[2]);
            pvector1.SetA(pointa[0]);
            pvector1.SetB(pointa[1]);
            pvector2.SetL(pointb[2]);
            pvector2.SetA(pointb[0]);
            pvector2.SetB(pointb[1]);
            values[0] = (Pvector)pvector1.Clone();
            values[1] = (Pvector)pvector2.Clone();
            return values;
        }

        //根据三角形三点获取三个角的角度
        public double[] GetTheHornOfTriangle(Pvector pointA, Pvector pointB, Pvector pointC)
        {
            double[] value = new double[3];
            //double lena=PointToPointLenght(pointA.GetL(),pointA.GetA(),pointA.GetB(),pointB.GetL(),pointB.GetA(),pointB.GetB());
            //double lenb=PointToPointLenght(pointB.GetL(),pointB.GetA(),pointB.GetB(),pointC.GetL(),pointC.GetA(),pointC.GetB());
            //double lenc=PointToPointLenght(pointA.GetL(),pointA.GetA(),pointA.GetB(),pointC.GetL(),pointC.GetA(),pointC.GetB());
            //value=GetTheHornOfTriangle(lena,lenb,lenc);
            ////三边分别是a、b、c,所对角为A、B、C三点
            double lenc = PointToPointLenght(pointA.GetL(), pointA.GetA(), pointA.GetB(), pointB.GetL(), pointB.GetA(), pointB.GetB());
            double lena = PointToPointLenght(pointB.GetL(), pointB.GetA(), pointB.GetB(), pointC.GetL(), pointC.GetA(), pointC.GetB());
            double lenb = PointToPointLenght(pointA.GetL(), pointA.GetA(), pointA.GetB(), pointC.GetL(), pointC.GetA(), pointC.GetB());
            value = GetTheHornOfTriangle(lena, lenb, lenc);
            return value;
        }

        //根据三角形三边长度获取三个角的角度
        public double[] GetTheHornOfTriangle(double dlineA, double dlineB, double dlineC)
        {
            double[] value = new double[3];
            double cosa = (dlineB * dlineB + dlineC * dlineC - dlineA * dlineA) / (2 * dlineB * dlineC);
            double cosb = (dlineA * dlineA + dlineC * dlineC - dlineB * dlineB) / (2 * dlineA * dlineC);
            double cosc = (dlineA * dlineA + dlineB * dlineB - dlineC * dlineC) / (2 * dlineA * dlineB);
            //double value1 = Math.Sin(Math.Acos(cosa) / Math.PI); ;//Math.toDegrees(Math.Acos(cosa));//弧度=度数/180*PI
            //double value2 = Math.Sin(Math.Acos(cosb) / Math.PI); ;//Math.toDegrees(Math.Acos(cosb));
            //double value3 = Math.Sin(Math.Acos(cosc) / Math.PI); ;//Math.toDegrees(Math.Acos(cosc));
            double value1=Math.Acos(cosa) * 180 / Math.PI;
            double value2=Math.Acos(cosb) * 180 / Math.PI;
            double value3=Math.Acos(cosc) * 180 / Math.PI;
            value[0] = value1;
            value[1] = value2;
            value[2] = value3;
            return value;
        }

        /// <summary>
        /// 实现数据的四舍五入法
        /// </summary>
        /// <param name="v">要进行处理的数据</param>
        /// <param name="x">保留的小数位数</param>
        /// <returns>四舍五入后的结果</returns>
        public double Round(double v, int x)
        {
            /*
            double d1 = Math.Round(1.25, 1);//1.2
            double d2 = Math.Round(1.24, 1);//1.2
            double d3 = Math.Round(1.26, 1);//1.3
            double d4 = Math.Round(1.35, 1);//1.4
             */
            bool isNegative = false;
            //如果是负数
            if (v < 0)
            {
                isNegative = true;
                v = -v;
            }

            int IValue = 1;
            for (int i = 1; i <= x; i++)
            {
                IValue = IValue * 10;
            }
            double Int = Math.Round(v * IValue + 0.5, 0);
            v = Int / IValue;

            if (isNegative)
            {
                v = -v;
            }

            return v;
        }

猜你喜欢

转载自blog.csdn.net/liangsongjun/article/details/82051424