Ejemplo n.º 1
0
        /// <summary>
        ///求两条异面直线的距离
        /// </summary>
        public double GetDistanceOfNonUniplanarRays(RayInfo otherRay)
        {
            if (this.Origin.equal(otherRay.Origin) || this.RayVector.IsParallel(otherRay.RayVector))//两射线共起点或平行时用此方法无法计算,且不符合条件
            {
                return(0);
            }
            SpectVector verticalLine = SpectVector.VectorCrossMultiply(this.RayVector, otherRay.RayVector);
            double      thi          = verticalLine.GetPhaseOfVector(new SpectVector(this.Origin, otherRay.Origin));

            if (thi > 90)
            {
                thi = 180 - thi;
            }
            return(this.Origin.GetDistance(otherRay.Origin) * Math.Cos(thi * Math.PI / 180));
        }
Ejemplo n.º 2
0
        public Point ray_cube2(RayInfo rayIn, ReceiveArea ra)//求与长方体的后面的交点;
        {
            double x = (ra.OriginPoint.Y + ra.rxWidth - rayIn.Origin.Y) / rayIn.RayVector.b * rayIn.RayVector.a + rayIn.Origin.X;
            double z = (ra.OriginPoint.Y + ra.rxWidth - rayIn.Origin.Y) / rayIn.RayVector.b * rayIn.RayVector.c + rayIn.Origin.Z;

            if (x >= ra.OriginPoint.X && x <= (ra.OriginPoint.X + ra.rxLength) && z >= ra.OriginPoint.Z && z <= (ra.OriginPoint.Z + ra.spacing))
            {
                Point temp = new Point(x, ra.OriginPoint.Y + ra.rxWidth, z);
                return(temp);
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 ///求镜像点
 /// </summary>
 ///  <param name="mirrorFace">镜像面</param>
 /// <returns>镜像点</returns>
 public Point GetMirrorPoint(Face mirrorFace)
 {
     if (mirrorFace.SwitchToSpaceFace().JudgeIfPointInFace(this))
     {
         return(this);
     }
     else
     {
         Point crossPoint  = new RayInfo(this, mirrorFace.NormalVector).GetCrossPointBetweenStraightLineAndFace(mirrorFace.SwitchToSpaceFace());
         Point mirrorPoint = new Point();
         mirrorPoint.X = 2 * crossPoint.X - this.x;
         mirrorPoint.Y = 2 * crossPoint.Y - this.y;
         mirrorPoint.Z = 2 * crossPoint.Z - this.z;
         return(mirrorPoint);
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        ///求平面外一条直线在该平面上的投影
        /// </summary>
        /// <param name="viewPoint">平面外一条直线</param>
        /// <returns>平面外一条直线在该平面上的投影</returns>
        public RayInfo GetProjectionRayInFace(RayInfo viewRay)
        {
            double dotProduct = this.normalVector.a * viewRay.RayVector.a +
                                this.normalVector.b * viewRay.RayVector.b + this.normalVector.c * viewRay.RayVector.c;

            if (Math.Abs(dotProduct) < 0.00000001)
            {
                return(new RayInfo(this.GetProjectionPointInFace(viewRay.Origin), viewRay.RayVector));
            }
            else
            {
                Point rayPointInFace = this.GetProjectionPointInFace(viewRay.Origin);
                Point crossPoint     = viewRay.GetCrossPointBetweenStraightLineAndFace(this);
                return(new RayInfo(rayPointInFace, crossPoint));
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 求细小的被分割一部分的圆柱体表面每一圈的点,只取两个圆的点
        /// </summary>
        /// <param name="divisionNumber">一圈的三角形的个数</param>
        /// <param name="surplsAngle">被切后圆截面所剩的角度</param>
        /// <param name="unitVectorU">下底圆所在平面上一个向量U</param>
        /// <param name="unitVectorV">下底圆所在平面上一个向量与U垂足的向量V</param>
        /// <returns></returns>
        private List <List <Point> > GetSmallSurfaceDivisionTrianglePoints(int divisionNumber, double surplsAngle, SpectVector unitVectorU, SpectVector unitVectorV)
        {
            //参考论文:基本体素的三角形面单元剖分方法-李鸿亮
            //现在每个圆上取点,再组成三角面
            List <List <Point> > divisionTrianglePoints = new List <List <Point> >();
            RayInfo ZVectorRay         = new RayInfo(this.bottomCirclePoint, this.topCirclePoint);
            double  H                  = this.topCirclePoint.GetDistance(this.bottomCirclePoint);
            double  L                  = surplsAngle / 360 * 2 * Math.PI * this.radius;
            double  a                  = L / divisionNumber;
            double  beta               = (surplsAngle * Math.PI / 180) / (2 * divisionNumber);
            Point   currentCenterPoint = this.bottomCirclePoint;

            for (int j = 0; j < 2; j++)
            {
                if (j == 1)
                {
                    currentCenterPoint = this.topCirclePoint;
                }
                List <Point> circlePoints = new List <Point>();
                //第一个点
                circlePoints.Add(this.GetPointInCircumference(currentCenterPoint, this.radius, unitVectorU, unitVectorV, 0.01));
                int i = 1;
                if (j % 2 == 0)//处于偶数层时
                {
                    while (i < divisionNumber)
                    {
                        circlePoints.Add(this.GetPointInCircumference(currentCenterPoint, this.radius, unitVectorU, unitVectorV, 2 * i * beta));
                        i++;
                    }
                }
                else//处于奇数层,奇数层要比偶数层多一个点
                {
                    while (i <= divisionNumber)
                    {
                        circlePoints.Add(this.GetPointInCircumference(currentCenterPoint, this.radius, unitVectorU, unitVectorV, (2 * i - 1) * beta));
                        i++;
                    }
                }
                //最后一个点
                circlePoints.Add(this.GetPointInCircumference(currentCenterPoint, this.radius, unitVectorU, unitVectorV, surplsAngle * Math.PI / 180 - 0.01));
                divisionTrianglePoints.Add(circlePoints);
            }
            return(divisionTrianglePoints);
        }
Ejemplo n.º 6
0
        public Point GetCrossPointWithRay(RayInfo oneRay)
        {
            double       high        = this.bottomCirclePoint.GetDistance(this.topCirclePoint);
            List <Point> crossPoints = this.Intersect(this.bottomCirclePoint, this.topCirclePoint, this.radius, high, oneRay.Origin, oneRay.GetPointOnRayVector(1));

            if (crossPoints.Count == 1)
            {
                return(crossPoints[0]);
            }
            if (crossPoints.Count > 1)
            {
                Point nearestPoint = crossPoints[0];
                for (int j = 1; j < crossPoints.Count; j++)
                {
                    if (nearestPoint.GetDistance(oneRay.Origin) > crossPoints[j].GetDistance(oneRay.Origin))
                    {
                        nearestPoint = crossPoints[j];
                    }
                }
                return(nearestPoint);
            }
            return(null);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 用于计算在一次绕射和两次相邻绕射中将各个点的信息添加到pointList中的过程
        /// </summary>
        /// <param name="tempPoints">临时点,栈用于将绕射点前倒序的反射点顺序输出</param>
        /// <param name="beforeTriangles">存放绕射前的三角面</param>
        /// <param name="afterTiangles">存放绕射后的三角面</param>
        /// <param name="beforeMirror">存放绕射前的镜像点</param>
        /// <param name="afterMirror">存放绕射后的镜像点</param>
        /// <param name="pointList"></param>
        /// <returns>顺序存储的各个点的坐标</returns>
        private static List <Point> GetPointListOfOneOrTwoAdjacentDiffractPath(
            Stack <Point> tempPoints, Stack <Face> beforeTriangles, Stack <Face> afterTiangles,
            Stack <Point> beforeMirror, Stack <Point> afterMirror)
        {
            List <Point> pointList = new List <Point>();

            while (beforeTriangles.Count != 0)
            {
                RayInfo tempRay = new RayInfo(tempPoints.Peek(), beforeMirror.Pop());
                if (tempRay.GetCrossPointWithFace(beforeTriangles.Peek()) != null)
                {
                    tempPoints.Push(tempRay.GetCrossPointWithFace(beforeTriangles.Pop()));
                }
                else
                {
                    return(new List <Point>());
                }
            }
            while (tempPoints.Count != 0)
            {
                pointList.Add(tempPoints.Pop());
            }
            while (afterTiangles.Count != 0)
            {
                RayInfo tempRay = new RayInfo(pointList[pointList.Count - 1], afterMirror.Pop());
                if (tempRay.GetCrossPointWithFace(afterTiangles.Peek()) != null)
                {
                    pointList.Add(tempRay.GetCrossPointWithFace(afterTiangles.Pop()));
                }
                else
                {
                    return(new List <Point>());
                }
            }
            return(pointList);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// 求点到直线的距离
 /// </summary>
 /// <param name="straightLine">直线</param>
 /// <returns>点到直线的距离</returns>
 public double GetDistanceToLine(RayInfo straightLine)
 {
     return(this.GetDistanceToLine(straightLine.Origin, straightLine.RayVector));
 }
Ejemplo n.º 9
0
        /// <summary>
        /// 已知一条棱上的一个点和这条棱,求一条射线从这个点出发(与这个棱的角度一定)到达另一个已知棱的方向向量
        /// </summary>
        /// <param name="beginPoint">起始点</param>
        /// <param name="angle">与起始点所在棱的夹角</param>
        /// <param name="targetEdge">另一条已知棱</param>
        /// <returns>返回参数中方向向量为求得的方向向量,点为在另一个已知棱上的点</returns>
        public List <RayInfo> getVectorFromEdge2EdgeWithAngle(Point beginPoint, double angle, AdjacentEdge targetEdge)
        {
            List <RayInfo> returnRays = new List <RayInfo>();
            double         x1         = targetEdge.startPoint.X - beginPoint.X;
            double         y1         = targetEdge.startPoint.Y - beginPoint.Y;
            double         z1         = targetEdge.startPoint.Z - beginPoint.Z;
            double         a1         = this.lineVector.a * targetEdge.lineVector.a + this.lineVector.b * targetEdge.lineVector.b + this.lineVector.c * targetEdge.lineVector.c;
            double         b1         = this.lineVector.a * x1 + this.lineVector.b * y1 + this.lineVector.c * z1;
            double         p          = Math.Cos(angle * Math.PI / 180) * Math.Cos(angle * Math.PI / 180) *
                                        (this.lineVector.a * this.lineVector.a + this.lineVector.b * this.lineVector.b + this.lineVector.c * this.lineVector.c);
            double a = p * (targetEdge.lineVector.a * targetEdge.lineVector.a + targetEdge.lineVector.b * targetEdge.lineVector.b + targetEdge.lineVector.c * targetEdge.lineVector.c) - a1 * a1;
            double b = p * 2 * (targetEdge.lineVector.a * x1 + targetEdge.lineVector.b * y1 + targetEdge.lineVector.c * z1) - 2 * a1 * b1;
            double c = p * (x1 * x1 + y1 * y1 + z1 * z1) - b1 * b1;

            RayInfo     returnRay   = null;
            SpectVector returnSV    = null;
            Point       returnPoint = null;

            double t;

            if (Math.Abs(a) < 0.000001)//此时方程只有一个解,且一定正确,只需判断是否在棱上即可
            {
                t = -c / b;
                double x = targetEdge.lineVector.a * t + targetEdge.startPoint.X;
                if ((x - targetEdge.startPoint.X) * (x - targetEdge.endPoint.X) <= 0)
                {
                    returnPoint = new Point(targetEdge.lineVector.a * t + targetEdge.startPoint.X,
                                            targetEdge.lineVector.b * t + targetEdge.startPoint.Y, targetEdge.lineVector.c * t + targetEdge.startPoint.Z);
                    returnSV = new SpectVector(targetEdge.lineVector.a * t + targetEdge.startPoint.X - beginPoint.X,
                                               targetEdge.lineVector.b * t + targetEdge.startPoint.Y - beginPoint.Y,
                                               targetEdge.lineVector.c * t + targetEdge.startPoint.Z - beginPoint.Z);
                    returnRay = new RayInfo(returnPoint, returnSV);
                    returnRays.Add(returnRay);
                }
            }
            else//此时方程有两个解,存在两种情况,一种是其中一个可能是由cos的平方产生的,需对所产生的点进行判断,舍去错误点;
                //另一种情况是,两个解都在追面上,但其中一个不在棱上而在棱延长线上,这种情况也应该舍去
                //{
                //    double delta = b * b - 4 * a * c;
                //    if (delta >= 0)
                //    {
                //        t = (-b + Math.Sqrt(delta)) / 2 / a;
                //        returnPoint = new Point(targetEdge.lineVector.a * t + targetEdge.startPoint.X,
                //            targetEdge.lineVector.b * t + targetEdge.startPoint.Y, targetEdge.lineVector.c * t + targetEdge.startPoint.Z);
                //        SpectVector tempVector=new SpectVector(beginPoint,returnPoint);
                //        if (Math.Abs(SpectVector.VectorPhase(this.lineVector, tempVector) - angle) > 0.0001)//如果所求解需舍去
                //        {
                //            t = (-b - Math.Sqrt(delta)) / 2 / a;
                //            returnPoint.X = targetEdge.lineVector.a * t + targetEdge.startPoint.X;
                //            returnPoint.Y = targetEdge.lineVector.b * t + targetEdge.startPoint.Y;
                //            returnPoint.Z = targetEdge.lineVector.c * t + targetEdge.startPoint.Z;
                //        }
                //        double x = targetEdge.lineVector.a * t + targetEdge.startPoint.X;
                //        double y = targetEdge.lineVector.b * t + targetEdge.startPoint.Y;
                //        double z = targetEdge.lineVector.c * t + targetEdge.startPoint.Z;
                //        if ((x - targetEdge.startPoint.X) * (x - targetEdge.endPoint.X) - 0.0001 <= 0
                //            && (y - targetEdge.startPoint.Y) * (y - targetEdge.endPoint.Y) - 0.0001 <= 0
                //            && (z - targetEdge.startPoint.Z) * (z - targetEdge.endPoint.Z) - 0.0001 <= 0)//判断点是否在第二条棱上
                //        {
                //            returnSV = new SpectVector(targetEdge.lineVector.a * t + targetEdge.startPoint.X - beginPoint.X,
                //                targetEdge.lineVector.b * t + targetEdge.startPoint.Y - beginPoint.Y,
                //                targetEdge.lineVector.c * t + targetEdge.startPoint.Z - beginPoint.Z);
                //            returnRay = new RayInfo(returnPoint, returnSV);
                //            returnRays.Add(returnRay);
                //        }
                //        else
                //        {
                //            t = (-b - Math.Sqrt(delta)) / 2 / a;
                //            x = targetEdge.lineVector.a * t + targetEdge.startPoint.X;
                //            y = targetEdge.lineVector.b * t + targetEdge.startPoint.Y;
                //            z = targetEdge.lineVector.c * t + targetEdge.startPoint.Z;
                //            if ((x - targetEdge.startPoint.X) * (x - targetEdge.endPoint.X) - 0.0001 <= 0
                //                && (y - targetEdge.startPoint.Y) * (y - targetEdge.endPoint.Y) - 0.0001 <= 0
                //                && (z - targetEdge.startPoint.Z) * (z - targetEdge.endPoint.Z) - 0.0001 <= 0)
                //            {
                //                returnSV = new SpectVector(targetEdge.lineVector.a * t + targetEdge.startPoint.X - beginPoint.X,
                //                targetEdge.lineVector.b * t + targetEdge.startPoint.Y - beginPoint.Y,
                //                targetEdge.lineVector.c * t + targetEdge.startPoint.Z - beginPoint.Z);
                //                returnRay = new RayInfo(returnPoint, returnSV);
                //            }
                //        }
                //    }
            {
                double delta = b * b - 4 * a * c;
                //这是两个交点的第一个解
                t = (-b + Math.Sqrt(delta)) / 2 / a;
                double x = targetEdge.lineVector.a * t + targetEdge.startPoint.X;
                double y = targetEdge.lineVector.b * t + targetEdge.startPoint.Y;
                double z = targetEdge.lineVector.c * t + targetEdge.startPoint.Z;
                returnPoint = new Point(x, y, z);
                if ((x - targetEdge.startPoint.X) * (x - targetEdge.endPoint.X) - 0.0001 <= 0 &&
                    (y - targetEdge.startPoint.Y) * (y - targetEdge.endPoint.Y) - 0.0001 <= 0 &&
                    (z - targetEdge.startPoint.Z) * (z - targetEdge.endPoint.Z) - 0.0001 <= 0)            //判断点是否在第二条棱上
                {
                    returnSV = new SpectVector(targetEdge.lineVector.a * t + targetEdge.startPoint.X - beginPoint.X,
                                               targetEdge.lineVector.b * t + targetEdge.startPoint.Y - beginPoint.Y,
                                               targetEdge.lineVector.c * t + targetEdge.startPoint.Z - beginPoint.Z);
                    returnRay = new RayInfo(returnPoint, returnSV);
                    //判断交点在不在反向延长线上,如果不在舍去,在的话添加到returnRays中
                    double angle2 = SpectVector.VectorPhase(new SpectVector(beginPoint, returnRay.Origin), this.lineVector);
                    if (Math.Abs(angle2 - angle) < 0.00001)
                    {
                        returnRays.Add(returnRay);
                    }
                }
                //两个交点的第二个解
                t = (-b - Math.Sqrt(delta)) / 2 / a;
                x = targetEdge.lineVector.a * t + targetEdge.startPoint.X;
                y = targetEdge.lineVector.b * t + targetEdge.startPoint.Y;
                z = targetEdge.lineVector.c * t + targetEdge.startPoint.Z;
                if ((x - targetEdge.startPoint.X) * (x - targetEdge.endPoint.X) - 0.0001 <= 0 &&
                    (y - targetEdge.startPoint.Y) * (y - targetEdge.endPoint.Y) - 0.0001 <= 0 &&
                    (z - targetEdge.startPoint.Z) * (z - targetEdge.endPoint.Z) - 0.0001 <= 0)
                {
                    returnSV = new SpectVector(targetEdge.lineVector.a * t + targetEdge.startPoint.X - beginPoint.X,
                                               targetEdge.lineVector.b * t + targetEdge.startPoint.Y - beginPoint.Y,
                                               targetEdge.lineVector.c * t + targetEdge.startPoint.Z - beginPoint.Z);
                    returnPoint = new Point(x, y, z);
                    returnRay   = new RayInfo(returnPoint, returnSV);
                    double angle2 = SpectVector.VectorPhase(new SpectVector(beginPoint, returnRay.Origin), this.lineVector);
                    if (Math.Abs(angle2 - angle) < 0.00001)
                    {
                        returnRays.Add(returnRay);
                    }
                }
            }
            //判断交点在不在射线的反向延长线上
            //for (int i=0;i<returnRays.Count;i++)
            //{
            //    double angle2 = SpectVector.VectorPhase(new SpectVector(beginPoint,returnRays[i].Origin), this.lineVector);
            //    if (Math.Abs(angle2 - angle) > 0.00001)
            //    {
            //        returnRays.RemoveAt(i);
            //    }
            //}

            return(returnRays);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// 求两条共面不平行的射线所在的直线的交点
        /// </summary>
        /// <param name="otherRay">另一条射线</param>
        /// <returns>交点</returns>
        public Point GetCrossPointWithOtherRay(RayInfo otherRay)
        {
            if (otherRay == null || Math.Abs(this.GetDistanceOfNonUniplanarRays(otherRay)) > 0.000001 || this.RayVector.IsParallel(otherRay.RayVector))
            {
                LogFileManager.ObjLog.error("求两条共面不平行直线交点时,输入为空,或者是两条异面直线或者平行直线");
                return(null);
            }
            double x1 = this.Origin.X, y1 = this.Origin.Y, z1 = this.Origin.Z;
            double x2 = otherRay.Origin.X, y2 = otherRay.Origin.Y, z2 = otherRay.Origin.Z;
            double a1 = this.RayVector.a, b1 = this.RayVector.b, c1 = this.RayVector.c;
            double a2 = otherRay.RayVector.a, b2 = otherRay.RayVector.b, c2 = otherRay.RayVector.c;
            Point  crossPoint = new Point();

            if (Math.Abs(a1) > 0.000001 && Math.Abs(a2) < 0.000001)
            {
                crossPoint.X = x2;
                double t1 = (x2 - x1) / a1;
                crossPoint.Y = b1 * t1 + y1;
                crossPoint.Z = c1 * t1 + z1;
                return(crossPoint);
            }
            else if (Math.Abs(a1) < 0.000001 && Math.Abs(a2) > 0.000001)
            {
                crossPoint.X = x1;
                double t2 = (x1 - x2) / a2;
                crossPoint.Y = b2 * t2 + y2;
                crossPoint.Z = c2 * t2 + z2;
                return(crossPoint);
            }
            else if (Math.Abs(b1) > 0.000001 && Math.Abs(b2) < 0.000001)
            {
                crossPoint.Y = y2;
                double t1 = (y2 - y1) / b1;
                crossPoint.X = a1 * t1 + x1;
                crossPoint.Z = c1 * t1 + z1;
                return(crossPoint);
            }
            else if (Math.Abs(b2) > 0.000001 && Math.Abs(b2) < 0.000001)
            {
                crossPoint.Y = y1;
                double t2 = (y1 - y2) / b2;
                crossPoint.X = a2 * t2 + x2;
                crossPoint.Z = c2 * t2 + z2;
                return(crossPoint);
            }
            else if (Math.Abs(c1) > 0.000001 && Math.Abs(c2) < 0.000001)
            {
                crossPoint.Z = z2;
                double t1 = (z2 - z1) / c1;
                crossPoint.X = a1 * t1 + x1;
                crossPoint.Y = b1 * t1 + y1;
                return(crossPoint);
            }
            else if (Math.Abs(c2) > 0.000001 && Math.Abs(c1) < 0.000001)
            {
                crossPoint.Z = z1;
                double t2 = (z1 - z2) / c2;
                crossPoint.X = a2 * t2 + x2;
                crossPoint.Y = b2 * t2 + y2;
                return(crossPoint);
            }
            else if (Math.Abs(a1) < 0.000001 && Math.Abs(a2) < 0.000001)
            {
                if ((b1 == 0 && b2 == 0) || (c1 == 0 && c2 == 0))
                {
                    LogFileManager.ObjLog.error("求两条共面不平行直线时,输入的直线方向向量a,b都为0,两直线平行");
                    return(null);
                }
                else
                {
                    double t1 = (y2 - y1 + (b2 / c2) * (z1 - z2)) / (b1 - (b2 / c2) * c1);
                    crossPoint.X = x1;
                    crossPoint.Y = b1 * t1 + y1;
                    crossPoint.Z = c1 * t1 + z1;
                }
                return(crossPoint);
            }
            else if (Math.Abs(b1) < 0.000001 && Math.Abs(b2) < 0.000001)
            {
                if (Math.Abs(c1) < 0.000001 && Math.Abs(c2) < 0.000001)//到这里说明a1,a2不为0
                {
                    LogFileManager.ObjLog.error("求两条共面不平行直线时,输入的直线方向向量a,b都为0,两直线平行");
                    return(null);
                }
                else
                {
                    double t1 = (x2 - x1 + (a2 / c2) * (z1 - z2)) / (a1 - (a2 / c2) * c1);
                    crossPoint.X = a1 * t1 + x1;
                    crossPoint.Y = y1;
                    crossPoint.Z = c1 * t1 + z1;
                }
                return(crossPoint);
            }
            else//到这步说明a1,a2,b1,b2都不为0
            {
                double t1 = Double.NaN;
                if ((a1 - (a2 / b2) * b1) != 0)
                {
                    t1 = (x2 - x1 + (a2 / b2) * (y1 - y2)) / (a1 - (a2 / b2) * b1);
                }
                //    double t1 = (y2 - y1 + (b2 / a2) * (x1 - x2)) / (b1 - (a1 / a2) * b2);
                else if ((a1 - (a2 / c2) * c1) != 0)
                {
                    t1 = (x2 - x1 + (a2 / c2) * (z1 - z2)) / (a1 - (a2 / c2) * c1);
                }
                crossPoint.X = a1 * t1 + x1;
                crossPoint.Y = b1 * t1 + y1;
                crossPoint.Z = c1 * t1 + z1;
                if (t1 == Double.NaN)
                {
                    throw new Exception("求共面不平行两射线交点时出错");
                }
                return(crossPoint);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// 求被分割一部分的圆台体表面的三角面单元
        /// </summary>
        /// <param name="divisionNumber">圆弧角的细分次数</param>
        /// <param name="surplsAngle">下底面所剩部分的角度</param>
        /// <param name="unitVectorU">下底圆所在平面上一个向量U</param>
        /// <param name="unitVectorV">下底圆所在平面上一个向量与U垂足的向量V</param>
        /// <returns></returns>
        public List <List <Triangle> > GetTruncatedSurfaceDivisionTriangles(int divisionNumber, double surplsAngle, SpectVector unitVectorU, SpectVector unitVectorV)
        {
            //参考论文:基本体素的三角形面单元剖分方法
            List <List <Triangle> > divisinTriangles = new List <List <Triangle> >();
            RayInfo circleCenterPointsRay            = new RayInfo(this.bottomCenterPoint, this.topCenterPoint);
            double  h                  = this.bottomCenterPoint.GetDistance(this.topCenterPoint);//圆台体的高
            double  l                  = Math.Sqrt((h * h + Math.Pow(this.bottomCircleRadius - this.topCircleRadius, 2)));
            double  L                  = this.bottomCircleRadius * l / (this.bottomCircleRadius - this.topCircleRadius);
            double  sinB               = h / l;
            double  theta              = 2 * Math.PI * this.bottomCircleRadius / L;//弧度制
            double  particalTheta      = surplsAngle / 360 * theta;
            int     j                  = 0;
            bool    flag               = true;
            double  alpha              = particalTheta / divisionNumber;
            double  triangleSideLength = 2 * L * Math.Sin(alpha / 2);//正三角形初始边长
            double  d                  = Math.Sqrt(3) * triangleSideLength / 2 + L - L * Math.Cos(alpha / 2);
            double  beta               = (surplsAngle * Math.PI / 180) / (2 * divisionNumber - 1);
            double  L1                 = L;
            double  sumd               = d;
            double  r1                 = L1 * theta / (2 * Math.PI);// 弧长除以2*PI
            Point   currentCenterPoint = this.bottomCenterPoint;

            while (flag)
            {
                double L2, r2, i = 0;
                Point  nextCenterPoint;
                if (sumd < l)
                {
                    L2 = L1 - d;
                    nextCenterPoint = circleCenterPointsRay.GetPointOnRayVector(sumd * sinB);
                }
                else
                {
                    L2              = L - l;
                    flag            = false;
                    nextCenterPoint = this.topCenterPoint;
                }
                r2 = L2 * theta / (2 * Math.PI);
                double k = 1, r3;
                Point  tempPoint;
                if (j % 2 == 0)//r1和r2交换
                {
                    r3                 = r1;
                    r1                 = r2;
                    r2                 = r3;
                    k                  = -1;
                    tempPoint          = currentCenterPoint;
                    currentCenterPoint = nextCenterPoint;
                    nextCenterPoint    = tempPoint;
                }
                List <Triangle> oneCircleTriangles = new List <Triangle>();
                while (i < 2 * divisionNumber)
                {
                    Point vertex1 = new Point(), vertex2 = new Point(), vertex3 = new Point(); //三角面的三个点
                    vertex1 = GetPointInCircumference(nextCenterPoint, r2, unitVectorU, unitVectorV, i * beta);
                    if (j % 2 == 1 && i == 0)                                                  //在单数的开始边界时
                    {
                        vertex2 = GetPointInCircumference(currentCenterPoint, r1, unitVectorU, unitVectorV, i * beta + 0.01);
                    }
                    else if (j % 2 == 1 && i == 2 * divisionNumber - 1)//在单数的结束边界时
                    {
                        vertex2 = GetPointInCircumference(currentCenterPoint, r1, unitVectorU, unitVectorV, i * beta - 0.01);
                    }
                    else
                    {
                        vertex2 = GetPointInCircumference(currentCenterPoint, r1, unitVectorU, unitVectorV, (i - k) * beta);
                    }
                    if (j % 2 == 0 && i == 0) //在双数开始边界时
                    {
                        vertex3 = GetPointInCircumference(currentCenterPoint, r1, unitVectorU, unitVectorV, i * beta + 0.01);
                    }
                    else if (j % 2 == 0 && i == 2 * divisionNumber - 1)//在双数结束边界时
                    {
                        vertex3 = GetPointInCircumference(currentCenterPoint, r1, unitVectorU, unitVectorV, i * beta - 0.01);
                    }
                    else
                    {
                        vertex3 = GetPointInCircumference(currentCenterPoint, r1, unitVectorU, unitVectorV, (i + k) * beta);
                    }
                    oneCircleTriangles.Add(new Triangle(vertex1, vertex2, vertex3));
                    r3                 = r1;
                    r1                 = r2;
                    r2                 = r3;
                    k                  = -k;
                    tempPoint          = currentCenterPoint;
                    currentCenterPoint = nextCenterPoint;
                    nextCenterPoint    = tempPoint;
                    i++;
                }
                divisinTriangles.Add(oneCircleTriangles);
                //
                if (this.bottomCenterPoint.GetDistance(currentCenterPoint) < this.bottomCenterPoint.GetDistance(nextCenterPoint))
                {
                    currentCenterPoint = nextCenterPoint;
                }
                L1 = Math.Min(L1, L2);
                r1 = L1 * theta / (Math.PI * 2);
                triangleSideLength = 2 * L1 * Math.Sin(alpha / 2);
                d     = Math.Sqrt(3) * triangleSideLength / 2 + L1 - L1 * Math.Cos(alpha / 2);
                sumd += d;
                j++;
            }

            return(divisinTriangles);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// 求被分割一部分的细小圆台体表面每个分割圆上的点,只有底面和顶面两个圆
        /// </summary>
        /// <param name="divisionNumber">圆弧角的细分次数</param>
        /// <param name="surplsAngle">下底面所剩部分的角度</param>
        /// <param name="unitVectorU">下底圆所在平面上一个向量U</param>
        /// <param name="unitVectorV">下底圆所在平面上一个向量与U垂足的向量V</param>
        /// <returns></returns>
        private List <List <Point> > GetSmallConeSurfaceDivisionTrianglePoints(int divisionNumber, double surplsAngle, SpectVector unitVectorU, SpectVector unitVectorV)
        {
            //参考论文:基本体素的三角形面单元剖分方法-李鸿亮
            //现在每个圆上取点,再组成三角面
            List <List <Point> > divisionTrianglePoints = new List <List <Point> >();
            RayInfo circleCenterPointsRay = new RayInfo(this.bottomCenterPoint, this.topCenterPoint);
            double  h                  = this.bottomCenterPoint.GetDistance(this.topCenterPoint);//圆台体的高
            double  l                  = Math.Sqrt((h * h + Math.Pow(this.bottomCircleRadius - this.topCircleRadius, 2)));
            double  L                  = this.bottomCircleRadius * l / (this.bottomCircleRadius - this.topCircleRadius);
            double  sinB               = h / l;
            double  theta              = 2 * Math.PI * this.bottomCircleRadius / L;//弧度制
            double  particalTheta      = surplsAngle / 360 * theta;
            int     j                  = 0;
            int     I                  = 2 * divisionNumber + 1;
            bool    flag               = true;
            double  alpha              = particalTheta / divisionNumber;
            double  triangleSideLength = 2 * L * Math.Sin(alpha / 2);//正三角形初始边长
            double  d                  = Math.Sqrt(3) * triangleSideLength / 2 + L - L * Math.Cos(alpha / 2);
            double  beta               = (surplsAngle * Math.PI / 180) / (2 * divisionNumber);
            double  currentL           = L;
            double  sumd               = 0;
            double  r                  = currentL * theta / (2 * Math.PI);// 弧长除以2*PI
            Point   currentCenterPoint = this.bottomCenterPoint;

            while (flag)
            {
                if (j == 1)
                {
                    flag = false;
                    currentCenterPoint = this.topCenterPoint;
                }
                List <Point> circlePoints = new List <Point>();
                int          i            = 1;
                //第一个点
                circlePoints.Add(this.GetPointInCircumference(currentCenterPoint, r, unitVectorU, unitVectorV, 0.01));
                if (j % 2 == 0)//处于偶数层时
                {
                    while (i < divisionNumber)
                    {
                        circlePoints.Add(this.GetPointInCircumference(currentCenterPoint, r, unitVectorU, unitVectorV, 2 * i * beta));
                        i++;
                    }
                }
                else//处于奇数层,奇数层要比偶数层多一个点
                {
                    while (i <= divisionNumber)
                    {
                        circlePoints.Add(this.GetPointInCircumference(currentCenterPoint, r, unitVectorU, unitVectorV, (2 * i - 1) * beta));
                        i++;
                    }
                }
                //最后一个点
                circlePoints.Add(this.GetPointInCircumference(currentCenterPoint, r, unitVectorU, unitVectorV, surplsAngle * Math.PI / 180 - 0.01));
                divisionTrianglePoints.Add(circlePoints);
                //
                currentL           = currentL - d;
                r                  = currentL * theta / (Math.PI * 2);
                triangleSideLength = 2 * currentL * Math.Sin(alpha / 2);
                d                  = Math.Sqrt(3) * triangleSideLength / 2 + currentL - currentL * Math.Cos(alpha / 2);
                sumd              += d;
                j++;
            }
            return(divisionTrianglePoints);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// 计算两次绕射的绕射点
        /// </summary>
        /// <param name="edge1">第一条绕射棱</param>
        /// <param name="edge2">第二条绕射棱</param>
        /// <param name="beginPoint">第一条绕射棱前的点</param>
        /// <param name="endPoint">第二条绕射棱后的点</param>
        /// <returns>用List的形式返回两个点的坐标</returns>
        public static List <Point> GetTwoDiffractionPoints(AdjacentEdge edge1, AdjacentEdge edge2, Point beginPoint, Point lastPoint)
        {
            //求由第二条棱的两端点确定的第一条棱无限延长线上的两绕射点
            Point p1 = edge1.GetInfiniteDiffractionPoint(beginPoint, edge2.StartPoint);
            Point p2 = edge1.GetInfiniteDiffractionPoint(beginPoint, edge2.EndPoint);

            if (p1 == null || p2 == null)
            {
                return(new List <Point>());
            }
            //第二条棱两端点
            Point p21 = edge2.StartPoint;
            Point p22 = edge2.EndPoint;


            AdjacentEdge tempLine = new AdjacentEdge(
                new Point(-10000 * edge2.LineVector.a + lastPoint.X, -10000 * edge2.LineVector.b + lastPoint.Y, -10000 * edge2.LineVector.c + lastPoint.Z),
                new Point(10000 * edge2.LineVector.a + lastPoint.X, 10000 * edge2.LineVector.b + lastPoint.Y, 10000 * edge2.LineVector.c + lastPoint.Z),
                edge2.LineVector);                                                                        //获得过点endPoint与第二条棱平行共面的长线段
            double         angle1  = SpectVector.VectorPhase(new SpectVector(p1, p21), edge2.LineVector); //得到第二条棱的入射角
            double         angle2  = SpectVector.VectorPhase(new SpectVector(p2, p22), edge2.LineVector);
            bool           isFirst = true;                                                                //用来判断是第一条路径,还是第二条路径
            List <RayInfo> rays    = edge2.getVectorFromEdge2EdgeWithAngle(p21, angle1, tempLine);

            if (rays.Count == 0)
            {
                return(new List <Point>());
            }
            RayInfo     ray1    = rays[0];//因为tempLine和edge2时平行的,所以只会有一条returnRay默认为returnRay[0]
            RayInfo     ray2    = rays[0];
            SpectVector vector1 = new SpectVector(lastPoint, ray1.Origin);
            SpectVector vector2 = new SpectVector(lastPoint, ray2.Origin);

            if (SpectVector.VectorDotMultiply(vector1, vector2) > 0 && rays.Count > 1)  //点乘大于0.表示在棱的外部
            {
                ray1    = rays[1];
                ray2    = rays[1];
                vector1 = new SpectVector(lastPoint, ray1.Origin);
                vector2 = new SpectVector(lastPoint, ray2.Origin);
                if (SpectVector.VectorDotMultiply(vector1, vector2) > 0)
                {
                    return(new List <Point>());
                }
                else
                {
                    //..
                    isFirst = false;//这时候lastPoint在第二条射线所形成的区域。
                }
            }

            double distance1 = lastPoint.GetDistanceToLine(p21, ray1.RayVector);
            double distance2 = lastPoint.GetDistanceToLine(p22, ray2.RayVector);

            List <Point> diffractPoints = new List <Point>();

            while (p1.GetDistance(p2) > 0.000001)
            {
                if (distance1 < 0.0001)
                {
                    if (edge1.JudgeIfPointInLineRange(p1))
                    {
                        diffractPoints.Add(p1);
                        diffractPoints.Add(p21);
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
                if (distance2 < 0.0001)
                {
                    if (edge1.JudgeIfPointInLineRange(p2))
                    {
                        diffractPoints.Add(p2);
                        diffractPoints.Add(p22);
                        break;
                    }
                    else
                    {
                        break;
                    }
                }

                Point          tempPoint          = new Point((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2, (p1.Z + p2.Z) / 2);
                double         tempAngle1         = SpectVector.VectorPhase(new SpectVector(beginPoint, tempPoint), edge1.LineVector);
                RayInfo        tempRay1           = new RayInfo(new Point(0, 0, 0), new SpectVector(0, 0, 1));//初始化射线,等待赋值
                double         tempAngle2         = 0;
                List <RayInfo> tempRaysOfTempLine = new List <RayInfo>();
                //RayInfo tempRay2 = new RayInfo(new Point(0, 0, 0), new SpectVector(0, 0, 1));//初始化射线,等待赋值
                double         tempDistance    = 0;
                List <RayInfo> tempRaysOfEdge2 = edge1.getVectorFromEdge2EdgeWithAngle(tempPoint, tempAngle1, edge2);
                if (isFirst && tempRaysOfEdge2.Count != 0)
                {
                    tempRay1           = tempRaysOfEdge2[0];
                    tempAngle2         = SpectVector.VectorPhase(tempRay1.RayVector, edge2.LineVector);
                    tempRaysOfTempLine = edge2.getVectorFromEdge2EdgeWithAngle(tempRay1.Origin, tempAngle2, tempLine);
                    if (tempRaysOfTempLine.Count != 0)
                    {
                        tempDistance = lastPoint.GetDistanceToLine(tempRaysOfTempLine[0].Origin, tempRaysOfTempLine[0].RayVector);
                    }
                }
                else if (edge1.getVectorFromEdge2EdgeWithAngle(tempPoint, tempAngle1, edge2).Count == 2 && isFirst == false)
                {
                    tempRay1           = tempRaysOfEdge2[1];
                    tempAngle2         = SpectVector.VectorPhase(tempRay1.RayVector, edge2.LineVector);
                    tempRaysOfTempLine = edge2.getVectorFromEdge2EdgeWithAngle(tempRay1.Origin, tempAngle2, tempLine);
                    if (tempRaysOfTempLine.Count != 0)
                    {
                        tempDistance = lastPoint.GetDistanceToLine(tempRaysOfTempLine[0].Origin, tempRaysOfTempLine[0].RayVector);
                    }
                }
                else
                {
                    return(new List <Point>());
                }
                RayInfo     tempRay2    = tempRaysOfTempLine[0];
                SpectVector tempVector1 = new SpectVector(lastPoint, ray1.Origin);
                SpectVector tempVector2 = new SpectVector(lastPoint, tempRay2.Origin);

                if (SpectVector.VectorDotMultiply(tempVector1, tempVector2) < 0)
                {
                    p2        = tempPoint;
                    p22       = tempRay1.Origin;
                    distance2 = tempDistance;
                    ray2      = tempRay2;
                }
                else
                {
                    p1        = tempPoint;
                    p21       = tempRay1.Origin;
                    distance1 = tempDistance;
                    ray1      = tempRay2;
                }
            }
            if (diffractPoints.Count == 0 && p1.GetDistance(p2) <= 0.000001)
            {
                Point  p3      = new Point((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2, (p1.Z + p2.Z) / 2);
                Point  p23     = edge2.GetInfiniteDiffractionPoint(p3, lastPoint);
                double angle11 = SpectVector.VectorPhase(new SpectVector(beginPoint, p3), edge1.LineVector);
                double angle12 = SpectVector.VectorPhase(new SpectVector(p3, p23), edge1.LineVector);
                if (Math.Abs(angle11 - angle12) < 0.001)
                {
                    diffractPoints.Add(p3);
                    diffractPoints.Add(p23);
                }
            }
            return(diffractPoints);
        }