private void OnSetDirectionX(GeoVectorProperty sender, GeoVector v) { if (Precision.IsNullVector(v)) { return; } polyline.ParallelogramMainDirection = v; // übernimmt nicht die Länge! }
public QuadTreeLine(IGeoObject go, GeoPoint sp, GeoPoint ep, Projection projection) { this.go = go; GeoPoint spp = projection.UnscaledProjection * sp; GeoPoint epp = projection.UnscaledProjection * ep; GeoPoint p3 = new GeoPoint(spp.x + (epp.y - spp.y), spp.y + (spp.x - epp.x)); this.sp = spp.To2D(); this.ep = epp.To2D(); GeoVector normal = GeoVector.ZAxis ^ (epp - spp); if (Precision.IsNullVector(normal)) { zmax = Math.Max(spp.z, epp.z); } else { try { plane = new Plane(spp, epp - spp, normal); zmax = double.MinValue; } catch (PlaneException) { zmax = Math.Max(spp.z, epp.z); } } // folgende 3 Gleichungen bestimmen den Z Wert (wenn die Linie nicht genau in Projektionsrichtung geht // fx*sp.x + fy*sp.y + c = spp.z; // fx*ep.x + fy*ep.y + c = epp.z; // fx*p3.x + fy*p3.y + c = spp.z; // nur damit die Lösung eindeutig bestimmt ist //double[,] m = new double[3, 3]; //m[0, 0] = this.sp.x; //m[0, 1] = this.sp.y; //m[0, 2] = 1.0; //m[1, 0] = this.ep.x; //m[1, 1] = this.ep.y; //m[1, 2] = 1.0; //m[2, 0] = p3.x; //m[2, 1] = p3.y; //m[2, 2] = 1.0; //double[,] b = new double[,] { { spp.z }, { epp.z }, { spp.z } }; //LinearAlgebra.Matrix mx = new CADability.LinearAlgebra.Matrix(m); //try //{ // LinearAlgebra.Matrix s = mx.Solve(new LinearAlgebra.Matrix(b)); // fx = s[0, 0]; // fy = s[0, 1]; // c = s[0, 2]; //} //catch (System.ApplicationException) //{ // Linie genau in Projektionsrichtung // // Z-Wert ist maximum // fx = 0.0; // fy = 0.0; // c = Math.Max(spp.z, epp.z); //} }
private void OnHeightPositionChanged(GeoPoint newPosition) { GeoPoint foot = Geometry.DropPL(newPosition, polyline.RectangleLocation, polyline.ParallelogramMainDirection); GeoVector directionY = newPosition - foot; if (!Precision.IsNullVector(directionY)) { polyline.SetRectangle(polyline.RectangleLocation, polyline.ParallelogramMainDirection, directionY); } }
private void OnWidthParallelPositionChanged(GeoPoint newPosition) { // an dem Hotspot für die Breite wurde gezogen GeoPoint foot = Geometry.DropPL(newPosition, polyline.ParallelogramLocation, polyline.ParallelogramSecondaryDirection); GeoVector directionX = newPosition - foot; if (!Precision.IsNullVector(directionX)) { polyline.SetParallelogram(polyline.ParallelogramLocation, directionX, polyline.ParallelogramSecondaryDirection); } }
// called by the VectorInput, when the user changes the direction private bool SetGeoVector(GeoVector vector) { if (Precision.IsNullVector(vector)) { return(false); } vector.Norm(); line.EndPoint = line.StartPoint + line.Length * vector; return(true); }
bool SetAxisVector(GeoVector vec) { if (Precision.IsNullVector(vec)) { return(false); } axisVector = vec; axisOrLine = true; updateOptional(); return(rotateOrg(true)); }
bool SetVector(GeoVector vec) { if (Precision.IsNullVector(vec)) { return(false); } vector = vec; // VectorOrHeight = true; // merken, ob Extrudier-Vektor oder Höhe extrudeMode = 2; // merken, ob Extrudier-Vektor oder Höhe optionalOrg(); return(extrudeOrg()); }
private bool SetDir(GeoVector vector) { if (!Precision.IsNullVector(vector)) { dirV = vector; dirV.Norm(); // Referenzlinien für die Abstände, abhängig vom Winkel! horDist.SetDistanceFromLine(centerPoint, centerPoint + (dirV ^ base.ActiveDrawingPlane.Normal)); verDist.SetDistanceFromLine(centerPoint, centerPoint + dirV); return(showMatrix()); } return(false); }
private bool SetAngle(GeoVector vector) { if (Precision.IsNullVector(vector)) { return(false); } vector.Norm(); GeoVector normal = picture.DirectionWidth ^ picture.DirectionHeight; picture.DirectionWidth = picture.DirectionWidth.Length * vector; picture.DirectionHeight = picture.DirectionHeight.Length * (normal ^ vector).Normalized; return(true); }
private void OnSetMinorAxis(GeoVectorProperty sender, GeoVector v) { GeoVector minax = v; // ändert auch den Radius GeoVector majax = minax ^ ellipse.Plane.Normal; // oder umgekehrt if (Precision.IsNullVector(minax) || Precision.IsNullVector(minax)) { return; // nix zu tun } minax.Norm(); minax = ellipse.MinorRadius * minax; majax.Norm(); majax = ellipse.MajorRadius * majax; ellipse.SetEllipseCenterAxis(ellipse.Center, majax, minax); }
private bool SetGeoVector(GeoVector vector) { if (Precision.IsNullVector(vector)) { return(false); } lineDir = vector; lineDir.Norm(); // if (curveInput.Fixed) // { objectPoint = base.BasePoint; // objectPoint = line.StartPoint; showLine(); // } return(true); }
private void OnSetMajorAxis(GeneralGeoPointAction sender, GeoPoint NewValue) { GeoVector majax = NewValue - ellipse.Center; // ändert auch den Radius GeoVector minax = ellipse.Plane.Normal ^ majax; // oder umgekehrt if (Precision.IsNullVector(minax) || Precision.IsNullVector(majax)) { return; // nix zu tun } minax.Norm(); minax = ellipse.MinorRadius * minax; majax.Norm(); majax = ellipse.MajorRadius * majax; ellipse.SetEllipseCenterAxis(ellipse.Center, majax, minax); majorAxisProperty.SetHotspotPosition(ellipse.Center + ellipse.MajorAxis); minorAxisProperty.SetHotspotPosition(ellipse.Center + ellipse.MinorAxis); }
private bool OnSetDirHeight(GeoVector v) { if (Precision.IsNullVector(v)) { return(false); } GeoVector normal = picture.DirectionWidth ^ picture.DirectionHeight; picture.DirectionHeight = v; if (rectangularValue) { picture.DirectionWidth = picture.DirectionWidth.Length * (v ^ normal).Normalized; } if (keepAspectRatioValue) { picture.DirectionWidth = picture.DirectionHeight.Length / picture.Bitmap.Height * picture.Bitmap.Width * picture.DirectionWidth.Normalized; } return(true); }
/// <summary> /// Determines the commomn plane of a point and a curve. Returns the common plane in the /// parameter and true if there is such a plane. Returns false, if the point lies not /// in the plane. <seealso cref="Precision"/> /// </summary> /// <param name="p">The point</param> /// <param name="c2">The curve</param> /// <param name="CommonPlane">The common plane</param> /// <returns>true, if there is a common plane, else false</returns> public static bool GetCommonPlane(GeoPoint p, ICurve c2, out Plane CommonPlane) { // kommt erstaunlicherweise ohne Zugriff auf die konkreten Kurven aus PlanarState ps2 = c2.GetPlanarState(); if (ps2 == PlanarState.NonPlanar) { CommonPlane = new Plane(Plane.StandardPlane.XYPlane, 0.0); // braucht leider ein Ergebnis return(false); } if (ps2 == PlanarState.Planar) { Plane p2 = c2.GetPlane(); if (Precision.IsPointOnPlane(p, p2)) { CommonPlane = p2; return(true); } } else { // UnderDetermined, also Linie oder so GeoVector v1 = p - c2.StartPoint; GeoVector v2 = c2.StartDirection; if (!Precision.SameDirection(v1, v2, false) && !Precision.IsNullVector(v1)) { Plane pl = new Plane(p, v1, v2); if (c2.IsInPlane(pl)) { CommonPlane = pl; return(true); } } } CommonPlane = new Plane(Plane.StandardPlane.XYPlane, 0.0); // braucht leider ein Ergebnis return(false); }
private bool showCutOff() { // nur wenn beide Kurven gültig sind if ((iCurve1 != null) && (iCurve2 != null) && (iCurve1 != iCurve2)) { Plane pl; // nur bei gemeisamer Ebene if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl)) { // !!! // owner = (iCurve1 as IGeoObject).Owner; // owner merken für löschen und Einfügen pl.Align(base.ActiveDrawingPlane, false); // Winkel anpassen ICurve2D curve1_2D = iCurve1.GetProjectedCurve(pl); // die 2D-Kurven if (curve1_2D is Path2D) { (curve1_2D as Path2D).Flatten(); } ICurve2D curve2_2D = iCurve2.GetProjectedCurve(pl); if (curve2_2D is Path2D) { (curve2_2D as Path2D).Flatten(); } ICurve newCurve = iCurve1.Clone(); // neue Kurve bis zum Schnittpunkt // hier die Schnittpunkte bestimmen und den cutPoint auf den nächsten Schnittpunt setzen GeoPoint2DWithParameter cutPoint; if (Curves2D.NearestPoint(curve1_2D.Intersect(curve2_2D), pl.Project(objectPoint), out cutPoint)) // runden war möglich { GeoVector2D v1 = curve1_2D.DirectionAt(cutPoint.par1); // die Richtung im Schnittpunkt if (cutPoint.par1 > 0.5) { v1 = v1.Opposite(); // evtl rumdrehen, falls am Ende } v1.Norm(); GeoVector2D v2 = curve2_2D.DirectionAt(cutPoint.par2); // die Richtung im Schnittpunkt if (cutPoint.par2 > 0.5) { v2 = v2.Opposite(); // evtl rumdrehen, falls am Ende } v2.Norm(); GeoVector2D v = (v1 + v2); // Winkelhalbierende if (Precision.IsNullVector(pl.ToGlobal(v))) { return(false); } v.Norm(); v = cutOffLen * v; // Winkelhalbierende mit Fas-Abstand GeoPoint2D dirPoint = cutPoint.p + v; // wird unten auch als Auswahlpunkt für die Richtung genutzt Line2D line2D = new Line2D(dirPoint, cutPoint.p); // Linie vorbesetzen, Punkte eigentlich egal if ((methodSelect == 0) || (methodSelect == 1)) { // 0: Länge cutOffLen = Seitenlänge Kurve1 1: Länge cutOffLen = Fasenlänge double sideLength; if (methodSelect == 1) // Länge cutOffLen = Fasenlänge // Geometrie, Pythagoras, bekannt Seite=cutOffLen, Winkel 1 = cutOffAng, Winkel 2 = Winkel der Kurven im Schnittpunkt { sideLength = cutOffLen * (Math.Cos(cutOffAng.Radian) + (Math.Sin(cutOffAng.Radian) / Math.Tan(Math.Abs(new SweepAngle(v1, v2).Radian)))); } else { sideLength = cutOffLen; } // neue Kurve bis zum Schnittpunkt synthetisieren, dazu: Schnittpunkt finden des Abschnitts mit der iCurve1 Ellipse arcTmp = Ellipse.Construct(); arcTmp.SetCirclePlaneCenterRadius(pl, pl.ToGlobal(cutPoint.p), sideLength); ICurve2D curveArc_2D = (arcTmp as ICurve).GetProjectedCurve(pl); // die 2D-Kurve GeoPoint2DWithParameter cutArc; GeoPoint2D startPoint; if (Curves2D.NearestPoint(curve1_2D.Intersect(curveArc_2D), dirPoint, out cutArc)) // war möglich { startPoint = cutArc.p; } else { return(false); } /* * double parCut; * // neue Kurve bis zum Schnittpunkt sythetisieren: * if (cutPoint.par1 <= 0.5) * { * newCurve.StartPoint = iCurve1.PointAt(cutPoint.par1); * parCut = (sideLength)/newCurve.Length; // der Parameter des Fasenpunktes * } * else * { * newCurve.EndPoint = iCurve1.PointAt(cutPoint.par1); * parCut = (newCurve.Length-sideLength)/newCurve.Length; // der Parameter des Fasenpunktes * } * GeoPoint2D startPoint = pl.Project(newCurve.PointAt(parCut)); * GeoVector2D vc = curve1_2D.DirectionAt(parCut); // die Richtung im Schnittpunkt */ GeoVector2D vc = curve1_2D.DirectionAt(curve1_2D.PositionOf(startPoint)); // die Richtung im Schnittpunkt if (cutPoint.par1 <= 0.5) { vc = vc.Opposite(); // evtl rumdrehen, falls am Ende } if (Geometry.OnLeftSide(dirPoint, startPoint, vc)) // Richtung festlegen für Winkeloffset { vc.Angle = vc.Angle + new SweepAngle(cutOffAng); } else { vc.Angle = vc.Angle - new SweepAngle(cutOffAng); } // Hilfslinie im Fasabstand, im Offsetwinkel line2D = new Line2D(startPoint, startPoint + vc); } if (methodSelect == 2) // Länge cutOffLen = Winkelhalbierendenlänge { v.Angle = v.Angle + new SweepAngle(cutOffAng); // Winkelhalbierendenwinkel + Offset // Hilfslinie im Fasabstand, senkrecht auf der Winkelhalbierenden v line2D = new Line2D(dirPoint, dirPoint + v.ToLeft()); } GeoPoint2DWithParameter cutPoint1; GeoPoint2DWithParameter cutPoint2; // schnittpunkte der Hilfslinie mit den beiden Kurven if (Curves2D.NearestPoint(curve1_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint1)) { if (Curves2D.NearestPoint(curve2_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint2)) { // da isse, die Fas-Linie, nur, wenn die Punkte echt auf der Kurve bis zum Schnittpunkt liegen: bool onCurve1, onCurve2; if (cutPoint.par1 > 0.5) { onCurve1 = (cutPoint1.par1 > 0.0) & (cutPoint1.par1 < 100); } // im Quasi-Parallelfall stehen in par1 riesige Werte else { onCurve1 = (cutPoint1.par1 < 1.0) & (cutPoint1.par1 > -100); } if (cutPoint.par2 > 0.5) { onCurve2 = (cutPoint2.par1 > 0.0) & (cutPoint2.par1 < 100); } else { onCurve2 = (cutPoint2.par1 < 1.0) & (cutPoint2.par1 > -100); } if (onCurve1 && onCurve2) { Line line = Line.Construct(); line.SetTwoPoints(pl.ToGlobal(cutPoint1.p), pl.ToGlobal(cutPoint2.p)); // Fasenlänge vorgegeben, aber mit obiger Berechnung falsch, da dort Linien vorausgesetzt werden if ((methodSelect == 1) && (Math.Abs(line.Length - cutOffLen) > Precision.eps)) { // jetzt mit Iteration annähern double parInd = 0.5; double parIndDelta = 0.25; for (int i = 0; i < 49; ++i) // 48 Schritte müssen reichen, par kann zwischen 0 und 1 liegen { GeoPoint2D startPoint = pl.Project(newCurve.PointAt(parInd)); GeoVector2D vc = curve1_2D.DirectionAt(parInd); // die Richtung im Schnittpunkt if (cutPoint.par1 <= 0.5) { vc = vc.Opposite(); // evtl rumdrehen, falls am Ende } if (Geometry.OnLeftSide(dirPoint, startPoint, vc)) // Richtung festlegen für Winkeloffset { vc.Angle = vc.Angle + new SweepAngle(cutOffAng); } else { vc.Angle = vc.Angle - new SweepAngle(cutOffAng); } // Hilfslinie im Fasabstand, im Offsetwinkel line2D = new Line2D(startPoint, startPoint + vc); if (Curves2D.NearestPoint(curve1_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint1)) { if (Curves2D.NearestPoint(curve2_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint2)) { // da isse, die Fas-Linie, nur, wenn die Punkte echt auf der Kurvr liegen: if (cutPoint.par1 > 0.5) { onCurve1 = (cutPoint1.par1 > 0.0) & (cutPoint1.par1 < 100); } // im Quasi-Parallelfall stehen in par1 riesige Werte else { onCurve1 = (cutPoint1.par1 < 1.0) & (cutPoint1.par1 > -100); } if (cutPoint.par2 > 0.5) { onCurve2 = (cutPoint2.par1 > 0.0) & (cutPoint2.par1 < 100); } else { onCurve2 = (cutPoint2.par1 < 1.0) & (cutPoint2.par1 > -100); } if (onCurve1 && onCurve2) { line.SetTwoPoints(pl.ToGlobal(cutPoint1.p), pl.ToGlobal(cutPoint2.p)); if ((Math.Abs(line.Length - cutOffLen) < Precision.eps)) // gefunden und raus { break; } else { if (line.Length < cutOffLen) { // Fase ist zu klein: Parameter parInd vergrößern parInd = parInd + parIndDelta; parIndDelta = parIndDelta / 2.0; // delta halbieren (Bisection!!) continue; // nächster Schritt in der For-Schleife } } } } } // alle anderen Fälle: // Fase ist zu gross: Parameter parInd verkleinern parInd = parInd - parIndDelta; parIndDelta = parIndDelta / 2.0; // delta halbieren (Bisection!!) } // for schleife Iteration } // Ende Iteration objectPoint = pl.ToGlobal(cutPoint.p); if (iCurve1.PositionOf(objectPoint) > 0.5) // am oberen Ende geklickt { iCurve1.Trim(0.0, iCurve1.PositionOf(line.StartPoint)); } else { iCurve1.Trim(iCurve1.PositionOf(line.StartPoint), 1.0); } if (iCurve2.PositionOf(objectPoint) > 0.5) // am oberen Ende geklickt { iCurve2.Trim(0.0, iCurve2.PositionOf(line.EndPoint)); objectPoint = iCurve2.StartPoint; } else { iCurve2.Trim(iCurve2.PositionOf(line.EndPoint), 1.0); objectPoint = iCurve2.EndPoint; } (line as IGeoObject).CopyAttributes(iCurve1 as IGeoObject); // objectPoint = pl.ToGlobal(cutPoint2.p); blk.Add(iCurve1 as IGeoObject); blk.Add(line); // base.FeedBack.AddSelected(iCurve1 as IGeoObject);// darstellen // base.FeedBack.AddSelected(line);// darstellen iCurve1 = iCurve2; // getrimmte Curve2 als Grundlage zur nächsten Berechnung return(true); } } } } } blk.Add(iCurve1 as IGeoObject); // unveränderte 1. Kurve zufügen, da kein Fasen möglich // base.FeedBack.AddSelected(iCurve1 as IGeoObject);// darstellen iCurve1 = iCurve2; // unveränderte Curve2 als Grundlage zur nächsten Berechnung } // base.ActiveObject = null; return(false); }