/// <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)); }
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); } }
/// <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); } }
/// <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)); } }
/// <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); }
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); }
/// <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); }
/// <summary> /// 求点到直线的距离 /// </summary> /// <param name="straightLine">直线</param> /// <returns>点到直线的距离</returns> public double GetDistanceToLine(RayInfo straightLine) { return(this.GetDistanceToLine(straightLine.Origin, straightLine.RayVector)); }
/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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); }