public static ParabolaEquation StretchParabola(ParabolaEquation equation, double factorX, double factorY) { ParabolaEquation newEquation = equation; //关键在对于次幂的修正,这里做的是以原点为中心的拉伸,因为是顶点式,所以只需要修改顶点就能做到平移 //要计算次幂的修正值,需要除顶点外的另外两个不对称点,这边就直接从方程中随便取两个点了 Point3d apex = equation.Apex; Point3d pt1 = equation.GetPoint(equation.h + 1000); Point3d pt2 = equation.GetPoint(equation.h + 2000); //点坐标计算上因数,即为拉伸后的曲线上坐标点 apex = new Point3d(apex.X * factorX, apex.Y * factorY, 0); pt1 = new Point3d(pt1.X * factorX, pt1.Y * factorY, 0); pt2 = new Point3d(pt2.X * factorX, pt2.Y * factorY, 0); //方程转换知 pow = log(y-k)-log(a) 底数为(x-h) //则前半部分的对数取值log(y-k) double lp1 = Math.Log(Math.Abs(pt1.Y - apex.Y), pt1.X - apex.X); double lp2 = Math.Log(Math.Abs(pt2.Y - apex.Y), pt2.X - apex.X); double lnX1 = Math.Log(Math.Abs(pt1.X - apex.X)); double lnX2 = Math.Log(Math.Abs(pt2.X - apex.X)); double lna = lnX1 * lnX2 * (lp1 - lp2) / (lnX2 - lnX1); double a = Math.Sign(pt1.Y - apex.Y) * Math.Pow(Math.E, lna); double h = apex.X; double k = apex.Y; double pow = Math.Round(Math.Log((pt1.Y - k) / a, pt1.X - h), 2); //纵向里面的修正应该就采用这个去修正就可以对上了 return(ParabolaEquation.CreateEquation(a, h, k, pow)); }
/// <summary> /// 这个函数线的方向和现有的还不太一样,还不能直接替换 TODO:修改点位顺序 /// </summary> public TxPolyline GetBottomPolyline(double precision) { double lengthFloorNormal = Math.Max(0, LengthHoriSup + LengthBottom - LengthCrossBeam - LengthFloor); //变高范围内底板等厚段长度,有可能是会小于0,但是目前没有去支持这样的情况,直接判定掉了 double lengthFloorChange = LengthHoriSup + LengthBottom - lengthFloorNormal - Math.Max(LengthCrossBeam + CvFloor, LengthHoriSup); //底板厚度变化段 double lengthFloorRemain = Math.Max(0, LengthBottom - lengthFloorNormal - lengthFloorChange); //剩余倒角段部分,未伸至全长 List <double> segFloorNormal = TX_Math.Design.BJ(lengthFloorNormal, precision, TX_Math.Design.BJType.Average); List <double> segFloorChange = TX_Math.Design.BJ(lengthFloorChange, precision, TX_Math.Design.BJType.Average); List <double> segFloorRemain = TX_Math.Design.BJ(lengthFloorRemain, precision, TX_Math.Design.BJType.Average); List <double> segCtl = new List <double>(); segCtl.AddRange(segFloorRemain); segCtl.AddRange(segFloorChange); segCtl.AddRange(segFloorNormal); TxPolyline result = new TxPolyline(); //添加墩顶水平段 if (LengthHoriSup > 0) { result.AddVertexAt(new Point3d(-LengthHoriSup, 0, 0)); } ParabolaEquation bottomEquation = this.BottomEquation; //从左往右顺序添加节点 double tempX = 0; for (int i = 0; i < segCtl.Count; i++) { Point3d tempPt = bottomEquation.GetPoint(tempX); result.AddVertexAt(tempPt); tempX += segCtl[i]; } //添加顶点 result.AddVertexAt(BottomEquation.Apex); return(result); }
/// <summary> /// 这个函数线的方向和现有的还不太一样,还不能直接替换 TODO:修改点位顺序 /// </summary> public TxPolyline GetFloorPolyline(double precision) { //一种是虚交点,这个应该是直接用方程计算 //一种是算控制点分段计算 if (IsByVirtualPoint) { double lengthFloorChange = LengthFloor - CvFloor; //底板厚度变化段 List <double> segFloor = TX_Math.Design.BJ(lengthFloorChange, precision, TX_Math.Design.BJType.Average); Point3d apex = new Point3d(LengthBottom, MaxBeamHeight - MinBeamHeight + MinFloorThick, 0); Point3d pt2 = new Point3d(0, MaxFloorThick, 0); ParabolaEquation equation = ParabolaEquation.CreateEquation(PowOfFloor, apex, pt2); TxPolyline result = new TxPolyline(); //从左往右顺序添加节点 double tempX = CvFloor; for (int i = 0; i < segFloor.Count; i++) { Point3d tempPt = equation.GetPoint(tempX); result.AddVertexAt(tempPt); tempX += segFloor[i]; } //添加顶点 result.AddVertexAt(apex); return(result); } else { double lengthFloorNormal = Math.Max(0, LengthHoriSup + LengthBottom - LengthCrossBeam - LengthFloor); //变高范围内底板等厚段长度,有可能是会小于0,但是目前没有去支持这样的情况,直接判定掉了 double lengthFloorChange = LengthHoriSup + LengthBottom - lengthFloorNormal - Math.Max(LengthCrossBeam + CvFloor, LengthHoriSup); // 底板厚度变化段 List <double> segFloorNormal = TX_Math.Design.BJ(lengthFloorNormal, precision, TX_Math.Design.BJType.Average); List <double> segFloorChange = TX_Math.Design.BJ(lengthFloorNormal, precision, TX_Math.Design.BJType.Average); List <double> segCtl = new List <double>(); segCtl.AddRange(segFloorChange); segCtl.AddRange(segFloorNormal); //底板上缘看原先的书写是底板厚度的变化值是按照抛物线来计算的,与底板下缘线型采用抛物线有一些不一样 Point3d apexFloor = new Point3d(LengthFloor, 0, 0); Point3d pt2Floor = new Point3d(0, MaxFloorThick - MinFloorThick, 0); ParabolaEquation equationFloor = ParabolaEquation.CreateEquation(PowOfFloor, apexFloor, pt2Floor); TxPolyline result = new TxPolyline(); //这里有个异常情况是倒角段也没伸出平段,这里特殊处理一下添加一个平段 if (LengthCrossBeam + CvFloor - LengthHoriSup < 0) { result.AddVertexAt(new Point3d(LengthCrossBeam + CvFloor - LengthHoriSup, MaxFloorThick, 0)); } //从左往右顺序添加节点 double tempX = Math.Max(0, LengthCrossBeam + CvFloor - LengthHoriSup); for (int i = 0; i < segCtl.Count; i++) { Point3d tempPt = BottomEquation.GetPoint(tempX); double thick = equationFloor.GetY(tempX); tempPt += Vector3d.YAxis * thick; result.AddVertexAt(tempPt); tempX += segCtl[i]; } //添加顶点 result.AddVertexAt(BottomEquation.Apex + Vector3d.YAxis * MinFloorThick); return(result); } }