/// <summary> /// Check Arc segment is collinear. /// </summary> /// <param name="arcSegment">Arc Segment</param> /// <param name="toleranceLevel">Tolerance Level</param> /// <returns>return true if two vectors are collinear</returns> public static bool IsCollinear(IArcSegment3D arcSegment, double toleranceLevel = MathConstants.ZeroGeneral) { Vector3D vector1 = GeomOperation.Subtract(arcSegment.StartPoint, arcSegment.IntermedPoint); Vector3D vector2 = GeomOperation.Subtract(arcSegment.IntermedPoint, arcSegment.EndPoint); return(IsCollinear(vector1, vector2, toleranceLevel)); }
/// <summary> /// Creates an arc segment from another arc segment. /// </summary> /// <param name="source">Source segment</param> public ArcSegment3D(IArcSegment3D source) : base(source) { if (source != null) { Name = (source as ElementBase).Name; intMedPoint = new Point3D(source.IntermedPoint.X, source.IntermedPoint.Y, source.IntermedPoint.Z); SubscribeEvents(this.intMedPoint); } }
internal ParabolaProperty(IArcSegment3D parabolicArc) { Matrix = new Matrix44(); IsValid = CalculateParabolaProperty(parabolicArc); if (!IsValid) { var seg = new ArcSegment3D(parabolicArc.StartPoint, parabolicArc.IntermedPoint, parabolicArc.EndPoint); ParabolaLength = GeomOperation.GetLength(seg); } }
/// <summary> /// Creates an Parabola from another segment Parabola. /// </summary> /// <param name="segmentParabola">Parabola Segment</param> public ParabolaSegment3D(IArcSegment3D segmentParabola) : base(segmentParabola) { if (segmentParabola != null) { Name = (segmentParabola as ElementBase).Name; intermediatePoint = new Point3D(segmentParabola.IntermedPoint.X, segmentParabola.IntermedPoint.Y, segmentParabola.IntermedPoint.Z); SubscribeEvents(intermediatePoint); } parabolaProperty = null; }
/// <summary> /// Convert the points of segment based on baseGeometry /// </summary> /// <param name="matrix">LCS matrix of baseGeometry</param> /// <param name="baseGeometry">Based on this region, the given segment is modifed</param> /// <param name="segment">Input segment object</param> /// <param name="isIndependent">Segment is independent</param> /// <param name="modifyInput">If true, given segment object is modified. Otherwise prepare new segment object</param> /// <returns>Segment object which is based on baseGeometry</returns> public static ISegment3D GetSegmentOnRegion(IMatrix44 matrix, IRegion3D baseGeometry, ISegment3D segment, bool isIndependent = true, bool modifyInput = true) { if (baseGeometry == null || segment == null) { return(null); } if (matrix == null) { matrix = GetMatrixPlane(baseGeometry); } if (!modifyInput) { segment = segment.CloneSegment(); } ILineSegment3D line = segment as ILineSegment3D; if (line != null) { if (isIndependent) { line.StartPoint = GetPointOnRegion(matrix, baseGeometry, line.StartPoint); } line.EndPoint = GetPointOnRegion(matrix, baseGeometry, line.EndPoint); return(line); } IArcSegment3D arc = segment as IArcSegment3D; if (arc != null) { if (isIndependent) { arc.StartPoint = GetPointOnRegion(matrix, baseGeometry, arc.StartPoint); } arc.IntermedPoint = GetPointOnRegion(matrix, baseGeometry, arc.IntermedPoint); arc.EndPoint = GetPointOnRegion(matrix, baseGeometry, arc.EndPoint); return(arc); } throw new NotSupportedException(); }
/// <summary> /// Calculate Point on parabola. /// </summary> /// <param name="segmentParabola">Segment Parabola</param> /// <param name="relativePosition">Relative Position</param> /// <param name="point">Point On Parabola</param> /// <returns>true if given input are valid</returns> internal bool GetPointOnParabola(IArcSegment3D segmentParabola, double relativePosition, ref IPoint3D point) { if (segmentParabola == null) { throw new ArgumentNullException(); } if (!IsValid) { IPoint3D a = segmentParabola.StartPoint; IPoint3D b = segmentParabola.IntermedPoint; point = GeomOperation.Add(GeomOperation.Multiply(b, relativePosition), GeomOperation.Multiply(a, 1 - relativePosition)); return(true); } double x = 0; // CIH - nejak jsem ty Abs nepochopil // if (Math.Abs(relativePosition).IsLesser(0.0)) // { // x = parabolaProperty.ParabolicArcX1; // } // else if (Math.Abs(relativePosition - 1.0).IsLesser(0.0)) // { // x = parabolaProperty.ParabolicArcX2; // } // else if (Math.Abs(parabolaProperty.ParabolaAxisAngle).IsLesser(0.0)) if (relativePosition.IsEqual(0.0)) { x = ParabolicArcX1; } else if (relativePosition.IsEqual(1.0)) { x = ParabolicArcX2; } //else if (ParabolaAxisAngle.IsLesser(0.0)) //{ // x = relativePosition * (ParabolicArcX2 - ParabolicArcX1) + ParabolicArcX1; //} else { x = 0.0; int it = 100; double pom = relativePosition * ParabolaLength + GetLengthToCurve(ParabolicArcX1); double caa = 4 * ParabolaAxisAngle * ParabolaAxisAngle; double len = pom; do { x += len / Math.Sqrt(1 + caa * x * x); len = pom - GetLengthToCurve(x); }while ((!len.IsZero(MathConstants.ZeroGeneral)) && (--it > 0)); //while ((!Math.Abs(len).IsLesser(0.0)) && (--it > 0)); if (Math.Abs(len) > 1e-8) { return(false); } } Vector3D normline = Matrix.AxisX; Vector3D ortho = Matrix.AxisY; point = GeomOperation.Add(segmentParabola.IntermedPoint, normline * x + ParabolaAxisAngle * ortho * x * x); return(true); }
/// <summary> /// Calculate the property of parabola. /// </summary> /// <param name="parabolicArc">Segment Parabola</param> /// <returns>true if given parabola segment is valid to calculate Length</returns> private bool CalculateParabolaProperty(IArcSegment3D parabolicArc) { Vector3D cb = GeomOperation.Subtract(parabolicArc.EndPoint, parabolicArc.IntermedPoint); Vector3D ncb = cb.Normalize; Vector3D ca = GeomOperation.Subtract(parabolicArc.StartPoint, parabolicArc.IntermedPoint); Vector3D nca = ca.Normalize; double d = ~(ncb * nca); //if (Math.Abs(d).IsLesser(0.0, MathConstants.ZeroGeneral)) if (Math.Abs(d).IsZero(1e-5)) { Vector3D vv = GeomOperation.Subtract(parabolicArc.EndPoint, parabolicArc.StartPoint); Vector3D normalizedLine = vv.Normalize; double parabolaX1 = normalizedLine | ca; double parabolaX2 = normalizedLine | cb; if (parabolaX2 < parabolaX1) { normalizedLine = -normalizedLine; parabolaX1 = -parabolaX1; parabolaX2 = -parabolaX2; } ParabolaAxisAngle = 0.0; ParabolicArcX1 = parabolaX1; ParabolicArcX2 = parabolaX2; ParabolaLength = vv.Magnitude; //SwapParabolicSegment(ref normalizedLine, ref parabolaX1, ref parabolaX2); //ParabolaLength = ~vv; //ParabolicArcX1 = normalizedLine | ca; //ParabolicArcX2 = normalizedLine | cb; //double parX1 = ParabolicArcX1; //double parX2 = ParabolicArcX2; //SwapParabolicSegment(ref normalizedLine, ref parX1, ref parX2); //ParabolicArcX1 = parX1; //ParabolicArcX2 = parX2; //Vector3D localY = new Vector3D(0, 0, 0); //if ((normalizedLine.DirectionZ - 1.0).IsZero()) //{ // localY.DirectionY = 1.0; //} //else if (normalizedLine.DirectionZ.IsZero()) //{ // localY.DirectionZ = 1.0; //} //else //{ // localY.DirectionX = -normalizedLine.DirectionX; // localY.DirectionY = -normalizedLine.DirectionY; // localY.DirectionZ = ((normalizedLine.DirectionX * normalizedLine.DirectionX) + (normalizedLine.DirectionY * normalizedLine.DirectionY)) / normalizedLine.DirectionZ; // localY = localY.Normalize; //} //Vector3D vectOrtho = GeomOperation.Rotate(localY, normalizedLine, 0.0); //ParabolaAxisAngle = (vectOrtho | ca) / (ParabolicArcX1 * ParabolicArcX1); //Matrix.AxisX = normalizedLine; //Matrix.AxisY = vectOrtho; //Matrix.AxisZ = (normalizedLine * vectOrtho).Normalize; //ParabolaLength = GetLengthToCurve(ParabolicArcX2) - GetLengthToCurve(ParabolicArcX1); //ParabolaLength = ~vv; return(false); } double parabolaAngle = 0.0; Vector3D vectorOrtho = new Vector3D(); Vector3D normalizedVector = new Vector3D(); bool repeat = false; do { if (!CalculateParabolaPlane(ca, cb, ref parabolaAngle, ref vectorOrtho, ref normalizedVector, repeat)) { return(false); } Vector3D normalLine = vectorOrtho * normalizedVector; double parabolaX1 = normalLine | ca; double parabolaX2 = normalLine | cb; if (parabolaX2 < parabolaX1) { normalLine = -normalLine; parabolaX1 = -parabolaX1; parabolaX2 = -parabolaX2; } ParabolicArcX1 = parabolaX1; ParabolicArcX2 = parabolaX2; //ParabolicArcX1 = normalLine | ca; //ParabolicArcX2 = normalLine | cb; //double parX1 = ParabolicArcX1; //double parX2 = ParabolicArcX2; //SwapParabolicSegment(ref normalLine, ref parX1, ref parX2); //ParabolicArcX1 = parX1; //ParabolicArcX2 = parX2; ParabolaAxisAngle = (vectorOrtho | ca) / (ParabolicArcX1 * ParabolicArcX1); Matrix.AxisX = normalLine; Matrix.AxisY = vectorOrtho; Matrix.AxisZ = normalizedVector; ParabolaLength = GetLengthToCurve(ParabolicArcX2) - GetLengthToCurve(ParabolicArcX1); double d1 = Math.Sqrt(((parabolicArc.StartPoint.X - parabolicArc.IntermedPoint.X) * (parabolicArc.StartPoint.X - parabolicArc.IntermedPoint.X)) + ((parabolicArc.StartPoint.Y - parabolicArc.IntermedPoint.Y) * (parabolicArc.StartPoint.Y - parabolicArc.IntermedPoint.Y)) + ((parabolicArc.StartPoint.Z - parabolicArc.IntermedPoint.Z) * (parabolicArc.StartPoint.Z - parabolicArc.IntermedPoint.Z))); double d2 = Math.Sqrt(((parabolicArc.EndPoint.X - parabolicArc.IntermedPoint.X) * (parabolicArc.EndPoint.X - parabolicArc.IntermedPoint.X)) + ((parabolicArc.EndPoint.Y - parabolicArc.IntermedPoint.Y) * (parabolicArc.EndPoint.Y - parabolicArc.IntermedPoint.Y)) + ((parabolicArc.EndPoint.Z - parabolicArc.IntermedPoint.Z) * (parabolicArc.EndPoint.Z - parabolicArc.IntermedPoint.Z))); if (!repeat) { if (ParabolaLength.IsLesser(d1 + d2)) { repeat = true; } } else { repeat = false; } }while (repeat); return(true); }