/// <summary> /// Checks, whether the LineType2d crosses an other LineType or not. In this method, bounded lines are /// considered. If the cross point is between P and Q and also between the P and Q of the other line /// then the result is true, otherwise it would be false. /// </summary> /// <param name="L">An other LineType to check for crossing</param> /// <returns>true, if a cross point exists between P and Q, otherwise false is returned</returns> public bool CrossBounded(LineType2d L) { double lam, mue; bool result = Cross(L, out lam, out mue); if (!result) { return(result); } if (Utils.Less(0, lam)) { return(false); } if (Utils.Less(0, mue)) { return(false); } if (Utils.Less(lam, 1)) { return(false); } if (Utils.Less(mue, 1)) { return(false); } return(true); }
/// <summary> /// Overrides the equals-method and returns true, if point P and the direction are equal. /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { LineType2d L = (LineType2d)obj; if ((Utils.Equals(L.Direction & Direction, 0) && (Utils.Equals(Direction & (L.P - P), 0)))) { return(true); } return(false); }
/// <summary> /// Calculates the cross point with an other LineType L, if this exists. /// In this case the result is true. With the parameters <b>lam</b> and <b>mue</b> you /// can calculate the cross point by <b>Value(lam)</b> resp. <b>L.value(mue)</b> /// </summary> /// <param name="L">The other line to calculate the cross point</param> /// <param name="lam">Parameter to calculate the cross point with Value(lam)</param> /// <param name="mue">Parameter to calculate the cross point with L.Value(mue)</param> /// <returns></returns> public bool Cross(LineType2d L, out double lam, out double mue) { lam = -1; mue = -1; double d = Direction & L.Direction; if (!(System.Math.Abs(d) < 0.00000000001)) { mue = (Direction & (Q - L.P)) / d; lam = (L.Direction & (P - L.Q)) / d; return(true); } return(false); }
/// <summary> /// Creates an arc by tree points P,Q and R. /// </summary> /// <param name="P">First point</param> /// <param name="Q">Second point</param> /// <param name="R">Third point</param> public Arc(xy P, xy Q, xy R) { LineType2d L1 = new LineType2d((P + Q) * 0.5, (Q - P).normal()); LineType2d L2 = new LineType2d((Q + R) * 0.5, (R - Q).normal()); double Lam, Mue; if (L1.Cross(L2, out Lam, out Mue)) { Center = L1.Value(Lam); aRadius = bRadius = Center.dist(P); Alfa = getAngle(P); Beta = getAngle(R); ClockWise = ((R - Q) & (P - Q)) < 0; } }
/// <summary> /// Overrides the <see cref="Curve.setAtang"/>-method /// </summary> /// <param name="value">starttangent</param> protected override void setAtang(xy value) { _At = value; atangSetted = true; if (btangSetted) { double lam, mue; LineType2d l1 = new LineType2d(A, value); LineType2d l2 = new LineType2d(B, _Bt); if (l1.Cross(l2, out lam, out mue)) { ControlPoint = l1.Value(lam); } Dirty = true; } }
/// <summary> /// Crosses the Curve with an other curve by crossing the interpolating polygonarray. /// <seealso cref="Cross(Curve,double, double , out double , out double)"/> /// </summary> /// <param name="Curve">The other Curve</param> /// <param name="lam">Parameter to evaluate with the value method ( this.value(lam))</param> /// <param name="mue">>Parameter to evaluate with the value method of Curve ( Curve.value(mue))</param> /// <returns>True if there is a crosspoint else false.</returns> public bool Cross(Curve Curve, out double lam, out double mue) { lam = 0; mue = 0; xyArray A = new xyArray(Resolution + 1); ToArray(A, 0); xyArray B = new xyArray(Curve.Resolution + 1); ; Curve.ToArray(B, 0); A.RemoveZeros(); B.RemoveZeros(); for (int i = 0; i < A.Count - 1; i++) { LineType2d L1 = new LineType2d(A[i], A[i + 1] - A[i]); if (!L1.Direction.Equals(new xy(0, 0))) { for (int j = 0; j < B.Count - 1; j++) { LineType2d L2 = new LineType2d(B[j], B[j + 1] - B[j]); bool solution = L1.Cross(L2, out lam, out mue); if (solution) { if ((lam >= -0.000001) && (lam <= 1.000001) && (mue >= -0.00001) && (mue <= 1.000001)) { solution = L1.Cross(L2, out lam, out mue); lam = (i + lam) / (float)Resolution; mue = (j + mue) / (float)Curve.Resolution; return(true); } } } } } lam = -1; mue = -1; return(false); }
/// <summary> /// Overrides the <see cref="Curve.Slice"/>-method. /// </summary> /// <param name="from"></param> /// <param name="to"></param> public override void Slice(double from, double to) { xy T1 = Derivation(from).normalize(); xy T2 = Derivation(to).normalize(); xy _A = Value(from); xy _B = Value(to); if ((System.Math.Abs(T1 & T2) < 0.001) || (System.Math.Abs(from - to) < 0.001)) { ControlPoint = (_A + _B) * 0.5; A = _A; B = _B; Dirty = true; return; } LineType2d L1 = new LineType2d(_A, Derivation(from)); LineType2d L2 = new LineType2d(_B, Derivation(to)); double Lam = -1; double Mue = -1; L1.Cross(L2, out Lam, out Mue); xy Halbierung = (_A + _B) * 0.5; xy P1 = Value((from + to) * 0.5); xy _ControlPoint = L1.Value(Lam); double a = (P1 - Halbierung).length(); double b = (_ControlPoint - Halbierung).length(); Weight = a / (b - a); if (Weight < 0) { } A = _A; B = _B; ControlPoint = _ControlPoint; Dirty = true; }
/// <summary> /// Gets the intersection with another curve, which is calculated by iteration. /// <seealso cref="Cross(Curve , out double, out double)"/> /// </summary> /// <param name="Curve">The other curve</param> /// <param name="InLam">A start parameter for this curve which is "near" to the solution</param> /// <param name="InMue">A start parameter for the other curve which is "near" to the solution</param> /// <param name="NearLam">Solution parameter for this curve</param> /// <param name="NearMue">Solution parameter for the other curve</param> /// <returns>true if there is a crosspoint else false.</returns> public bool Cross(Curve Curve, double InLam, double InMue, out double NearLam, out double NearMue) { NearLam = InLam; NearMue = InMue; double _nearLam; double _nearMue; if (Double.IsNaN(Curve.Value(0).x)) { return(false); } if (Double.IsNaN(Value(0).x)) { return(false); } double di1 = (float)1 / (float)Resolution; double di2 = (float)1 / (float)Curve.Resolution; xy Q1; xy Q2; bool weiter = false; xy _A = Value(NearLam - di1 / 2); xy _B = Value(NearLam + di1 / 2); xy C = Curve.Value(NearMue - di2 / 2); xy D = Curve.Value(NearMue + di2 / 2); LineType2d L1 = new LineType2d(_A, _B - _A); LineType2d L2 = new LineType2d(C, D - C); if (L1.Cross(L2, out _nearLam, out _nearMue)) { NearLam = NearLam - di1 + _nearLam * di1; NearMue = NearMue - di2 + _nearLam * di2; } bool Left1 = false; bool Left2 = false; do { di1 = di1 / 2; di2 = di2 / 2; if ((NearLam / di1 - Utils.trunc(NearLam / di1)) > 0.5) { Left1 = false; _A = Value(NearLam); _B = Value(NearLam + di1); } else { Left1 = true; _A = Value(NearLam - di1); _B = Value(NearLam); } L1 = new LineType2d(_A, _B - _A); if (NearMue / di2 - Utils.trunc(NearMue / di2) > 0.5) { Left2 = false; C = Curve.Value(NearMue); D = Curve.Value(NearMue + di2); } else { Left2 = true; C = Curve.Value(NearMue - di2); D = Curve.Value(NearMue); } L2 = new LineType2d(C, D - C); weiter = false; if (L1.Cross(L2, out _nearLam, out _nearMue)) { if (Left1) { NearLam = NearLam - di1 + _nearLam * di1; } else { NearLam = NearLam + _nearLam * di1; } if (Left2) { NearMue = NearMue - di2 + _nearMue * di2; } else { NearMue = NearMue + _nearMue * di2; } weiter = true; } Q1 = Value(NearLam); Q2 = Curve.Value(NearMue); }while ((weiter) && (!Q1.Equals(Q2))); return(Q1.Equals(Q2) && (!Utils.Less(NearLam, 0)) && (!Utils.Less(1, NearLam)) && (System.Math.Abs(InMue - NearMue) < 0.2) && (System.Math.Abs(InLam - NearLam) < 0.2) && (!Utils.Less(NearMue, 0)) && (!Utils.Less(1, NearMue))); }