private void StartPoint(GeoPoint p) { if (!Precision.IsEqual(p, arcCenter)) { arcStartPoint = p; if (arcCenterInput.Fixed) { try { arcPlane = new Plane(arcCenter, arcCenter - arcStartPoint, base.ActiveDrawingPlane.Normal ^ ((GeoVector)(arcCenter - arcStartPoint))); arcPlane.Align(base.ActiveDrawingPlane, false); } catch (PlaneException) { arcPlane = new Plane(arcCenter, arcCenter - arcStartPoint, ((GeoVector)(arcCenter - arcStartPoint)) ^ base.ActiveDrawingPlane.DirectionX); arcPlane.Align(base.ActiveDrawingPlane, false, true); }; arcRad = Geometry.Dist(arcCenter, arcStartPoint); if (arcCenterInput.Fixed & arcEndPointInput.Fixed) { try { arcPlane = new Plane(arcCenter, arcStartPoint, arcEndPoint); arcPlane.Align(base.ActiveDrawingPlane, false, true); } catch (PlaneException) { arcPlane = base.ActiveDrawingPlane; }; } double endAbs = arc.SweepParameter + arc.StartParameter; startAng = new Angle(arc.Plane.Project(arcStartPoint), arc.Plane.Project(arcCenter)); // endAng = new SweepAngle(endAbs - startAng); arc.SetArcPlaneCenterRadiusAngles(arcPlane, arcCenter, arcRad, startAng, endAng); } } }
static public bool ruledSolidTest(GeoObjectList geoObjectList, Model model) { // Tested für SelectedObjectsAction, ob Eintrag enabled oder nicht bool temp; if ((geoObjectList.Count == 1) && (geoObjectList[0] is ICurve) && (findPath(geoObjectList[0], model, out temp) != null)) { // ein Element, Pfad und geschlossen return(true); } if ((geoObjectList.Count == 2) && (geoObjectList[0] is ICurve) && (geoObjectList[1] is ICurve)) { // zwei Elemente, auf geschlossene Pfade testen Path p1 = (findPath(geoObjectList[0], model, out temp)); Path p2 = (findPath(geoObjectList[1], model, out temp)); if ((p1 != null) && (p2 != null)) { if ((p1.GetPlanarState() == PlanarState.Planar) && (p2.GetPlanarState() == PlanarState.Planar)) // jeder Pfad in sich in einer Ebene { // beide eben, jetzt nur noch: unterschiedliche Ebenen: if (!Precision.IsEqual(p1.GetPlane(), p2.GetPlane())) { return(true); } } } } return(false); }
static public bool ruledFaceTest(GeoObjectList geoObjectList, Model model) { // Tested für SelectedObjectsAction, ob Eintrag enabled oder nicht bool temp; if ((geoObjectList.Count == 1) && (geoObjectList[0] is ICurve) && (findPath(geoObjectList[0], model, out temp) != null)) { // ein Element, Pfad return(true); } if ((geoObjectList.Count == 2) && (geoObjectList[0] is ICurve) && (geoObjectList[1] is ICurve)) { // zwei Elemente, auf Pfade testen Path p1 = (findPath(geoObjectList[0], model, out temp)); Path p2 = (findPath(geoObjectList[1], model, out temp)); if ((p1 != null) && (p2 != null)) { if ((p1.IsClosed && p2.IsClosed) || (!p1.IsClosed && !p2.IsClosed)) // OPenCascade will nur geschlossene oder nur offene { if (((p1 as ICurve).GetPlanarState() == PlanarState.Planar) && ((p2 as ICurve).GetPlanarState() == PlanarState.Planar)) // jeder Pfad in sich in einer Ebene { // beide eben, jetzt nur noch: unterschiedliche Ebenen: if (!Precision.IsEqual(p1.GetPlane(), p2.GetPlane())) { return(true); } } if ((((p1 as ICurve).GetPlanarState() == PlanarState.Planar) || (p1 as ICurve).GetPlanarState() == PlanarState.UnderDetermined) && (((p2 as ICurve).GetPlanarState() == PlanarState.Planar) || (p2 as ICurve).GetPlanarState() == PlanarState.UnderDetermined)) // jeder Pfad in sich in einer Ebene { // beide eben, jetzt nur noch: unterschiedliche Ebenen: return(true); } } } } return(false); }
private bool ruledFaceOrg() { if (!(Precision.IsEqual(p1.StartPoint, p2.StartPoint) && (Precision.IsEqual(p1.EndPoint, p2.EndPoint)))) // 1. Näherung, dass sie nicht gleich sind! { if ((p1.IsClosed && p2.IsClosed) || (!p1.IsClosed && !p2.IsClosed)) // OPenCascade will nur geschlossene oder nur offene { if ((((p1 as ICurve).GetPlanarState() == PlanarState.Planar) || (p1 as ICurve).GetPlanarState() == PlanarState.UnderDetermined) && (((p2 as ICurve).GetPlanarState() == PlanarState.Planar) || (p2 as ICurve).GetPlanarState() == PlanarState.UnderDetermined)) { // also nur Ebene Pfade mit unterschiedlichen Ebenen oder unbestimmt, z.B. Linien: if (((p1 as ICurve).GetPlanarState() == PlanarState.Planar) && ((p2 as ICurve).GetPlanarState() == PlanarState.Planar) && Precision.IsEqual((p1 as ICurve).GetPlane(), (p2 as ICurve).GetPlane())) { return(false); } // also was geeignetes dabei IGeoObject ss = Make3D.MakeRuledShell(p1, p2, Frame.Project); if (ss != null) { if (base.ActiveObject != null) { ss.CopyAttributes(base.ActiveObject); } // der block wird das neue aktive Objekt, er muss die Attribute tragen, weil sie später // wieder von ihm verlangt werden // ss.CopyAttributes(attrObject); base.ActiveObject = ss; // darstellen base.ShowActiveObject = true; return(true); } } } } base.ShowActiveObject = false; return(false); }
private bool ruledSolidOrg() { if (((p1 as ICurve).GetPlanarState() == PlanarState.Planar) && ((p2 as ICurve).GetPlanarState() == PlanarState.Planar)) { // also nur Ebene Pfade mit unterschiedlichen Ebenen: if (!Precision.IsEqual((p1 as ICurve).GetPlane(), (p2 as ICurve).GetPlane())) { // also was geeignetes dabei Solid ss = Make3D.MakeRuledSolid(p1, p2, Frame.Project); if (ss != null) { if (base.ActiveObject != null) { ss.CopyAttributes(base.ActiveObject); } // der block wird das neue aktive Objekt, er muss die Attribute tragen, weil sie später // wieder von ihm verlangt werden // ss.CopyAttributes(attrObject); base.ActiveObject = ss; // darstellen base.ShowActiveObject = true; return(true); } } } base.ShowActiveObject = false; return(false); }
private void EndPoint(GeoPoint p) { if (!Precision.IsEqual(p, coneStartPoint)) { coneDirZ = new GeoVector(coneStartPoint, p); if (height.Fixed) // die schon bestimmte Höhe benutzen! { coneDirZ = coneHeight * coneDirZ.Normalized; } else { coneHeight = coneDirZ.Length; } // coneDirX muss irgendwie senkrecht auf coneDirZ stehen. Hier: Hilfsvektor definieren mit der kleinsten Komponente von coneDirZ GeoVector vT = new GeoVector(1, 0, 0); // x am kleinsten if (Math.Abs(coneDirZ.y) < Math.Abs(coneDirZ.x)) { vT = new GeoVector(0, 1, 0); // y am kleinsten } if ((Math.Abs(coneDirZ.x) > Math.Abs(coneDirZ.z)) && (Math.Abs(coneDirZ.y) > Math.Abs(coneDirZ.z))) { vT = new GeoVector(0, 0, 1); // z am kleinsten } coneDirX = coneRadius1 * (vT ^ coneDirZ).Normalized; cone = Make3D.MakeCone(coneStartPoint, coneDirX, coneDirZ, coneRadius1, coneRadius2); cone.CopyAttributes(base.ActiveObject); base.ActiveObject = cone; } }
private static void RefineIntersectionPoint(Ellipse2D e1, Ellipse2D e2, ref GeoPoint2DWithParameter ip) { // hier mir Param arbeiten, da es sich auch um einen Ellipsenbogen handeln kann double par1 = e1.ParamOf(ip.p); double par2 = e2.ParamOf(ip.p); GeoPoint2D p1 = e1.PointAtParam(par1); GeoPoint2D p2 = e2.PointAtParam(par2); int counter = 0; while (!Precision.IsEqual(p1, p2)) { GeoVector2D d1 = e1.DirectionAtParam(par1); GeoVector2D d2 = e2.DirectionAtParam(par2); GeoPoint2D p; if (Geometry.IntersectLL(p1, d1, p2, d2, out p)) { par1 = e1.ParamOf(p); par2 = e2.ParamOf(p); p1 = e1.PointAtParam(par1); p2 = e2.PointAtParam(par2); ip.p = p; } else { break; } ++counter; if (counter > 100) { break; } } ip.par1 = e1.PositionOf(ip.p); // richtige Werte auch für Arc ip.par2 = e2.PositionOf(ip.p); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.IGeoObjectImpl.HasValidData ()"/> /// </summary> /// <returns></returns> public override bool HasValidData() { if (Precision.IsEqual(startPoint, endPoint)) { return(false); } return(true); }
private Boolean showEllipse() { if (!Precision.IsEqual(point1, point2) && !vector1.IsNullVector() && !vector2.IsNullVector()) { return(ellipse.SetEllipse2PointsDirections(point1, vector1, point2, vector2)); } return(false); }
/// <summary> /// Calculates the intersection points of the two curves. /// </summary> /// <param name="curve1">First curve</param> /// <param name="curve2">Second curve</param> /// <param name="par1">Resulting parameters for the first curve</param> /// <param name="par2">Resulting parameters for the second curve</param> /// <param name="intersection">Three dimensional intersection points</param> /// <returns>Number of intersection points</returns> public static int Intersect(ICurve curve1, ICurve curve2, out double[] par1, out double[] par2, out GeoPoint[] intersection) { // wenn es eine gemeinsame Ebene gibt, dann in dieser Ebene schneiden if (GetCommonPlane(curve1, curve2, out Plane pln)) { ICurve2D c2d1 = curve1.GetProjectedCurve(pln); ICurve2D c2d2 = curve2.GetProjectedCurve(pln); GeoPoint2DWithParameter[] ips = c2d1.Intersect(c2d2); // geht die Parametrierung der projizierten Kurven analog zu den Originalen? // da wir ja nur in die Ebene Projizieren, in der sich duie Kurven ohnehin befinden, müsste das stimmen // das muss aber noch getestet werden par1 = new double[ips.Length]; par2 = new double[ips.Length]; intersection = new GeoPoint[ips.Length]; for (int i = 0; i < ips.Length; ++i) { par1[i] = ips[i].par1; par2[i] = ips[i].par2; intersection[i] = pln.ToGlobal(ips[i].p); } return(ips.Length); } // eine Linie und eine nichtebene Kurve noch gesondert prüfen if (curve1.GetPlanarState() == PlanarState.Planar) { double[] ips = curve2.GetPlaneIntersection(curve1.GetPlane()); List <double> lpar1 = new List <double>(); List <double> lpar2 = new List <double>(); List <GeoPoint> lip = new List <GeoPoint>(); for (int i = 0; i < ips.Length; ++i) { GeoPoint p = curve2.PointAt(ips[i]); double ppar1 = curve1.PositionOf(p); GeoPoint p1 = curve1.PointAt(ppar1); if (Precision.IsEqual(p, p1)) { lpar1.Add(ppar1); lpar2.Add(ips[i]); lip.Add(new GeoPoint(p, p1)); } } par1 = lpar1.ToArray(); par2 = lpar2.ToArray(); intersection = lip.ToArray(); return(par1.Length); } if (curve2.GetPlanarState() == PlanarState.Planar) { return(Intersect(curve2, curve1, out par2, out par1, out intersection)); } // Fehlt noch die Abfrage nach einer Linie, denn die ist ja nicht planar // allgemeiner Fall: zwei nicht ebene Kurven TetraederHull th1 = new TetraederHull(curve1); TetraederHull th2 = new TetraederHull(curve2); return(th1.Intersect(th2, out par1, out par2, out intersection)); }
private void EndPoint(GeoPoint p) { // definiert die Achse des Torus if (!Precision.IsEqual(p, torusCenterPoint)) { torusNormal = new GeoVector(torusCenterPoint, p); torus = Make3D.MakeTorus(torusCenterPoint, torusNormal, torusRadius1, torusRadius2); torus.CopyAttributes(base.ActiveObject); base.ActiveObject = torus; } }
/// <summary> /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.PerpendicularFoot (GeoPoint2D)"/> /// </summary> /// <param name="FromHere"></param> /// <returns></returns> public override GeoPoint2D[] PerpendicularFoot(GeoPoint2D FromHere) { if (Precision.IsEqual(FromHere, center)) { return(new GeoPoint2D[0]); } Angle a = new Angle(FromHere, center); return(new GeoPoint2D[] { new GeoPoint2D(center, radius, a), new GeoPoint2D(center, radius, a + SweepAngle.Opposite) }); }
private void SecondPoint(GeoPoint p) { // falls der 2. Punkt über einen Punkt im Raum über dem jetzigen Rechteck bestimmt wird: // der Lotfußpunkt von p auf die HauptAchse (x-Direction) // GeoPoint pl = Geometry.DropPL(p,line.RectangleLocation,line.ParallelogramMainDirection); GeoPoint pl = Geometry.DropPL(p, line.RectangleLocation, base.ActiveDrawingPlane.DirectionX); if ((!Precision.IsEqual(line.RectangleLocation, pl)) & (!Precision.IsEqual(pl, p))) { // Neues Rechteck mit neuer Orientierung im Raum, x-Vektor: Startpunkt-Lotfußpunkt y-Vektor: Lotfußpunkt-p line.SetRectangle(line.RectangleLocation, new GeoVector(line.RectangleLocation, pl), new GeoVector(pl, p)); } }
private void SecondPoint(GeoPoint p) { if (!Precision.IsEqual(line.RectangleLocation, p)) { GeoVector v = line.ParallelogramSecondaryDirection; if (!Precision.SameDirection(new GeoVector(line.RectangleLocation, p), v, false)) { line.SetRectangle(line.RectangleLocation, new GeoVector(line.RectangleLocation, p), v); } } }
private double HeightCalculate(GeoPoint MousePosition) { // falls die Höhe über einen Punkt im Raum über dem jetzigen Rechteck bestimmt wird: // der Lotfußpunkt von MousePosition auf die HauptAchse (x-Direction) GeoPoint p = Geometry.DropPL(MousePosition, line.RectangleLocation, line.ParallelogramMainDirection); if (!Precision.IsEqual(MousePosition, p)) { // Neues Rechteck mit neuer Orientierung im Raum, y-Vektor: Lotfußpunkt, Mausposition line.SetRectangle(line.RectangleLocation, line.ParallelogramMainDirection, new GeoVector(p, MousePosition)); // nun die Höhe zurückliefern return(line.RectangleHeight); } return(0); }
private Boolean showEllipse() { if (!Precision.IsEqual(point1, point2) && !vector1.IsNullVector() && !vector2.IsNullVector()) { if (ellipse.SetEllipseArc2PointsDirections(point1, vector1, point2, vector2, dir, base.ActiveDrawingPlane)) { base.MultiSolutionCount = 2; // zur schnellen Umschaltung der Richtung in OnDifferentSolution, s.u. return(true); } } base.MultiSolutionCount = 0; return(false); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.Orientation (GeoPoint)"/> /// </summary> /// <param name="p"></param> /// <returns></returns> public override double Orientation(GeoPoint p) { GeoPoint q = this.PointAt((GetLineIntersection(p, Normal))[0]); double d = q | p; if (Precision.IsEqual(q + d / Normal.Length * Normal, p)) { return(d); } else { return(-d); } }
private void SetDimLocation(GeoPoint p) { // der Lagepunkt der Bemassung if (((methodSelect == 1) || (methodSelect == 2)) & (dim.PointCount >= 2)) { mi.Fixed = true; // Abbruchkriterium für MultiPoint } if (dim.PointCount == 1) { if (!Precision.IsEqual(p, dim.GetPoint(0))) { dim.AddPoint(p); // falls erst ein punkt da ist: einen machen zur Darstellung! } } dim.DimLineRef = p; }
public override void OnDone() { base.ActiveObject = null; if (trimCurve != null) // nur dann gibts was zu tun! { using (base.Frame.Project.Undo.UndoFrame) { if (deleteObject) { owner.Remove(iCurve as IGeoObject); // original Löschen } else { if (iCurve.IsClosed) // geschlosene Kurve, also z.B. Kreis { iCurve.Trim(param2, param1); // an zwei Parametern geschnitten } else { // if (!Precision.IsEqual(trimCurve.StartPoint, iCurve.StartPoint) && !Precision.IsEqual(trimCurve.EndPoint, iCurve.EndPoint)) if ((param1 > 1e-8) && (param2 < (1.0 - 1e-8))) { // mittendrinn´da parameter beide innerhalb der Kurve! ICurve trimCurveTemp; trimCurveTemp = iCurve.Clone(); iCurve.Trim(0.0, param1); // Kurve auf das untere Stück verkürzt (trimCurveTemp as IGeoObject).CopyAttributes(iCurve as IGeoObject); trimCurveTemp.Trim(param2, 1.0); // Kopie als oberes Stück owner.Add(trimCurveTemp as IGeoObject); } else { if (Precision.IsEqual(trimCurve.StartPoint, iCurve.StartPoint)) // der Anfang muss weg { iCurve.Trim(param1, 1.0); } if (Precision.IsEqual(trimCurve.EndPoint, iCurve.EndPoint)) // das Ende muss weg { iCurve.Trim(0.0, param2); } } } } } } sourceCurveSave = sourceCurve; base.OnDone(); }
public InfiniteLine2D(GeoPoint2D startPoint, GeoPoint2D endPoint) { this.startPoint = startPoint; direction = endPoint - startPoint; Angle a = direction.Angle; if (Precision.IsEqual(a, Angle.A0) || Precision.IsEqual(a, Angle.A180)) { toXAxis = ModOp2D.Translate(0.0, -startPoint.y); } else { double l = -startPoint.y / direction.y; // != 0.0, da nicht horizontal double x = startPoint.x + l * direction.x; // double y = startPoint.y+l*direction.y; toXAxis = ModOp2D.Rotate(new GeoPoint2D(x, 0.0), new SweepAngle(-a)); } }
private void EndPoint(GeoPoint p) { arcEndPoint = p; // arc.SweepParameter = new SweepAngle(arc.StartParameter,new Angle(arc.Plane.Project(arcEndPoint),arc.Plane.Project(arcCenter)),ConstrDefaults.DefaultArcDirection); arcPlane = base.ActiveDrawingPlane; if (arcCenterInput.Fixed & arcStartPointInput.Fixed) { if (!Precision.IsEqual(arcEndPoint, arcCenter) & !Precision.IsEqual(arcEndPoint, arcStartPoint) & !Precision.IsEqual(arcCenter, arcStartPoint)) { try { arcPlane = new Plane(arcCenter, arcStartPoint, arcEndPoint); arcPlane.Align(base.ActiveDrawingPlane, false, true); } catch (PlaneException) { arcPlane = base.ActiveDrawingPlane; }; } } endAng = new SweepAngle(arc.StartParameter, new Angle(arc.Plane.Project(arcEndPoint), arc.Plane.Project(arcCenter)), arcDir); arc.SetArcPlaneCenterRadiusAngles(arcPlane, arcCenter, arcRad, startAng, endAng); }
private void SecondPoint(GeoPoint p) { endP = p; if (startPointInput.Fixed) { if (!Precision.IsEqual(startP, p)) { text.Location = new GeoPoint(startP, p); GeoVector v = new GeoVector(startP, p); // v.Length = textLen; v.Length = text.LineDirection.Length; text.LineDirection = v; Plane pl = new Plane(text.Location, text.LineDirection, base.ActiveDrawingPlane.Normal ^ text.LineDirection); text.GlyphDirection = pl.ToGlobal(textDir2D); } } else { text.Location = p; gPoint.Location = p; } }
/// <summary> /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.Trim (double, double)"/> /// </summary> /// <param name="StartPos"></param> /// <param name="EndPos"></param> /// <returns></returns> public override ICurve2D Trim(double StartPos, double EndPos) { if ((EndPos - StartPos) < (1.0 / vertex.Length)) { if (Precision.IsEqual(PointAt(StartPos), PointAt(EndPos))) { return(null); } } Polyline2D res = this.Clone() as Polyline2D; try { res.TrimOff(StartPos, EndPos); return(res); } catch (Polyline2DException) { // ein zu kurzes Stück wird dort nicht akzeptiert return(null); } }
private void TrimOff(double StartPos, double EndPos) { if (StartPos == 0.0 && EndPos == 0.0) { return; // nichts wird abgeschnitten } if (StartPos == 1.0 && EndPos == 1.0) { return; } bool beginning = (StartPos == 0.0 || (StartPos < 1.0 / vertex.Length && Precision.IsEqual(StartPoint, PointAt(StartPos)))); bool ending = (EndPos == 1.0 || (EndPos > (1.0 - (1.0 / vertex.Length)) && Precision.IsEqual(EndPoint, PointAt(EndPos)))); if (beginning && ending) { return; } if (beginning) { ICurve2D[] splt = Split(EndPos); this.vertex = (GeoPoint2D[])(splt[0] as Polyline2D).vertex.Clone(); this.length = -1; } else if (ending) { ICurve2D[] splt = Split(StartPos); this.vertex = (GeoPoint2D[])(splt[1] as Polyline2D).vertex.Clone(); this.length = -1; } else { GeoPoint2D endpoint = PointAt(EndPos); TrimOff(StartPos, 1.0); TrimOff(0.0, PositionOf(endpoint)); } }
private bool showLine() { ArrayList usable1Curves = new ArrayList(); ArrayList usable2Curves = new ArrayList(); ArrayList usable3Curves = new ArrayList(); Plane pl; Plane pl1; double mindist = double.MaxValue; if (tang1Curves == null) { return(false); } if (tang2Curves == null) { return(false); } // if (tang3Curves == null) return false; for (int i = 0; i < tang1Curves.Length; ++i) { for (int j = 0; j < tang2Curves.Length; ++j) { if (Curves.GetCommonPlane(tang1Curves[i], tang2Curves[j], out pl)) { if (tang3Curves == null) { return(true); // bei zwei bestimmten: sind in der gleichen Ebene } for (int k = 0; k < tang3Curves.Length; ++k) { if (Curves.GetCommonPlane(tang1Curves[i], tang3Curves[k], out pl1)) { if (Precision.IsEqual(pl, pl1)) { ICurve2D l2D1 = tang1Curves[i].GetProjectedCurve(pl); if (l2D1 is Path2D) { (l2D1 as Path2D).Flatten(); } ICurve2D l2D2 = tang2Curves[j].GetProjectedCurve(pl); if (l2D2 is Path2D) { (l2D2 as Path2D).Flatten(); } ICurve2D l2D3 = tang3Curves[k].GetProjectedCurve(pl); if (l2D3 is Path2D) { (l2D3 as Path2D).Flatten(); } GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, l2D2, l2D3, pl.Project(object1Point), pl.Project(object2Point), pl.Project(object3Point)); if (tangentPoints.Length > 0) { // eine gültige Linie ist gefunden //if (curve1Input.Fixed & curve2Input.Fixed & (tangentPoints.Length > 4)) //{ // int debug = 0; //} usable1Curves.Add(tang1Curves[i]); // zur lokalen Liste zufügen usable2Curves.Add(tang2Curves[j]); // zur lokalen Liste zufügen usable3Curves.Add(tang3Curves[k]); // zur lokalen Liste zufügen for (int l = 0; l < tangentPoints.Length; l += 4) { double dist = Geometry.Dist(tangentPoints[l + 1], pl.Project(object1Point)) + Geometry.Dist(tangentPoints[l + 2], pl.Project(object2Point)) + Geometry.Dist(tangentPoints[l + 3], pl.Project(object3Point)); if (dist < mindist) { mindist = dist; selected1 = usable1Curves.Count - 1; // merken, welche Kurven die aktuell benutzten sind selected2 = usable2Curves.Count - 1; selected3 = usable3Curves.Count - 1; // selSol / 6 entspricht div 6, um einige Zeilen tiefer weitere 6 Möglichkeiten auswählen zu können // (/ 4) und (* 4), da pro Lösung vier Punkte geliefert werden int m = (l + 4 * (Math.Abs(selSol) % (tangentPoints.Length / 4))) % tangentPoints.Length; center = tangentPoints[m]; circRad = Geometry.Dist(tangentPoints[m + 1], center); } } } if (mindist < double.MaxValue) { // base.MultiSolution = true; base.MultiSolutionCount = tangentPoints.Length / 4; circ.SetCirclePlaneCenterRadius(pl, pl.ToGlobal(center), circRad); tang1Curves = (ICurve[])usable1Curves.ToArray(typeof(ICurve)); // überschreibt die eigentliche Liste und wird unten an den Sender zurückgeliefert tang2Curves = (ICurve[])usable2Curves.ToArray(typeof(ICurve)); // überschreibt die eigentliche Liste und wird unten an den Sender zurückgeliefert tang3Curves = (ICurve[])usable3Curves.ToArray(typeof(ICurve)); // überschreibt die eigentliche Liste und wird unten an den Sender zurückgeliefert base.ShowActiveObject = true; return(true); } } } } } } } base.ShowActiveObject = false; base.MultiSolutionCount = 0; // base.MultiSolution = false; return(false); }
private void OnSetVertexPoint(GeoPointProperty sender, GeoPoint p) { int indexStartPoint = (int)sender.UserData.GetData("Index"); GeoPoint[] vtx = path.Vertices; if (indexStartPoint == 0) { if (path.IsClosed) { if (Precision.IsEqual(p, vtx[vtx.Length - 1])) { return; // das letzte Segment wird 0 } if (Precision.IsEqual(p, vtx[1])) { return; // das letzte Segment wird 0 } } } else { if (Precision.IsEqual(vtx[indexStartPoint - 1], p)) { return; // das Vorgänger-Segment wird 0 } } if (indexStartPoint == vtx.Length - 1) { if (path.IsClosed) { if (Precision.IsEqual(p, vtx[1])) { return; // das erste Segment wird 0 } } } else if (indexStartPoint < vtx.Length) { if (Precision.IsEqual(vtx[indexStartPoint + 1], p)) { return; // das Nachfolger-Segment wird 0 } } int indexEndPoint = -1; if (indexStartPoint == 0 && path.IsClosed) { // der 1. Punkt und geschlossen indexEndPoint = path.CurveCount - 1; // Endpunkt vom letzten Segment } else if (indexStartPoint == path.CurveCount) { // der letzte Punkt if (path.IsClosed) { indexEndPoint = indexStartPoint - 1; indexStartPoint = 0; } else { indexEndPoint = indexStartPoint - 1; indexStartPoint = -1; } } if (indexStartPoint > 0) { indexEndPoint = indexStartPoint - 1; } bool dbg1 = path.IsClosed; Path dbgpath = path.Clone() as Path; path.SetPoint(indexStartPoint, p, Path.ModificationMode.keepArcRatio); // versuchsweise bool dbg2 = path.IsClosed; if (dbg1 != dbg2) { dbgpath.SetPoint(indexStartPoint, p, Path.ModificationMode.keepArcRatio); // versuchsweise } // path.SetPoint(indexEndPoint, indexStartPoint, p); }
private bool showLine() { ArrayList usableCurves = new ArrayList(); // lokales Array, das die gültigen Kurven sammelt double mindist = double.MaxValue; for (int i = 0; i < perpCurves.Length; ++i) { Plane pl; if (Curves.GetCommonPlane(startPoint, perpCurves[i], out pl)) { ICurve2D l2D = perpCurves[i].GetProjectedCurve(pl); if (l2D is Path2D) { (l2D as Path2D).Flatten(); } GeoPoint2D[] perpPoints = l2D.PerpendicularFoot(pl.Project(startPoint)); if (perpPoints.Length > 0) { // eine gültige Kurve ist gefunden usableCurves.Add(perpCurves[i]); for (int j = 0; j < perpPoints.Length; ++j) { // double dist = Geometry.Dist(perpPoints[j],pl.Project(startPoint)); double dist = Geometry.Dist(perpPoints[j], pl.Project(objectPoint)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist endPoint = perpPoints[j]; } } } else { // beim Kreis oder Bogen vom Mittelpunkt aus gilt jeder Punkt if (l2D is Circle2D) { if (Precision.IsEqual((l2D as Circle2D).Center, pl.Project(startPoint))) { GeoPoint2D pp = l2D.PointAt(l2D.PositionOf(pl.Project(objectPoint))); double dist = Geometry.Dist(pp, pl.Project(objectPoint)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist endPoint = pp; } } } } } if (mindist < double.MaxValue) { line.SetTwoPoints(startPoint, pl.ToGlobal(endPoint)); perpCurves = (ICurve[])usableCurves.ToArray(typeof(ICurve)); // perpCurves wird mit den gültigen überschrieben und unten zur Anzeige zurückgegeben an den Sender base.ShowActiveObject = true; return(true); } } line.SetTwoPoints(startPoint, objectPoint); base.ShowActiveObject = true; return(false); }
private bool showRound() { // jetzt werden die Rundparameter bestimmt base.ActiveObject = null; base.FeedBack.ClearSelected(); if ((iCurve1 != null) && (iCurve2 != null) && (iCurve1 != iCurve2)) { Plane pl; if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl)) { if (composedSplit) { if (iCurveComposedSplit != null) { owner = (iCurveComposedSplit as IGeoObject).Owner; // owner merken für löschen und Einfügen } else { owner = ownerCreated; } } else { owner = (iCurve1 as IGeoObject).Owner; // owner merken für löschen und Einfügen } // owner = (iCurve1 as IGeoObject).Owner; // owner merken für löschen und Einfügen bool rndPos = false; // Runden möglich double distCP; // Entfernung Pickpunkt - Schnittpunkte GeoPoint2D arcP1 = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcP2 = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcCenter = new GeoPoint2D(0.0, 0.0); 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(); } // hier die Schnittpunkte bestimmen und den cutPoint auf den nächsten Schnittpunt setzen GeoPoint2DWithParameter cutPoint; rndPos = Curves2D.NearestPoint(curve1_2D.Intersect(curve2_2D), pl.Project(objectPoint), out cutPoint); if (rndPos) // runden war möglich { arcCenter = cutPoint.p; double locmin1, locmin2; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt locmin1 = 0.0; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt locmin2 = 0.0; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt double locmax1, locmax2; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt locmax1 = 1.0; locmax2 = 1.0; double locPar; // für den Fall: virtueller Schnittpunkt die Parametergrenzen anpassen locPar = curve1_2D.PositionOf(cutPoint.p); // position des Schnittpunktes auf der Kurve1 //if ( locPar > 0.5) locmax1 = locPar; //else locmin1 = locPar; if (locPar > 1.0) { locmax1 = locPar; } if (locPar < 0.0) { locmin1 = locPar; } locPar = curve2_2D.PositionOf(cutPoint.p); // position des Schnittpunktes auf der Kurve2 if (locPar > 1.0) { locmax2 = locPar; } if (locPar < 0.0) { locmin2 = locPar; } //if (locPar > 0.5) locmax2 = locPar; //else locmin2 = locPar; // Kreis synthetisieren arc.SetArcPlaneCenterRadius(pl, pl.ToGlobal(arcCenter), roundRad); ICurve2D curveArc_2D = (arc as ICurve).GetProjectedCurve(pl); // Schnittpunkte Kreisbogen mit Kurve 1 GeoPoint2DWithParameter[] cutPoints = curve1_2D.Intersect(curveArc_2D); distCP = double.MaxValue; for (int i = 0; i < cutPoints.Length; ++i) // Schleife über alle Schnittpunkte { // nur der Schnittpunkt innerhalb der Kurve if ((cutPoints[i].par1 > locmin1) & (cutPoints[i].par1 < locmax1)) { double distLoc = Geometry.Dist(cutPoints[i].p, pl.Project(objectPoint)); if (distLoc < distCP) { distCP = distLoc; arcP1 = cutPoints[i].p; // Schnittpunkt schonmal merken } //arcP1 = cutPoints[i].p; //break; } } // Schnittpunkte Kreisbogen mit Kurve 2 cutPoints = curve2_2D.Intersect(curveArc_2D); distCP = double.MaxValue; for (int i = 0; i < cutPoints.Length; ++i) // Schleife über alle Schnittpunkte { // nur der Schnittpunkt innerhalb der Kurve if ((cutPoints[i].par1 > locmin2) & (cutPoints[i].par1 < locmax2)) { double distLoc = Geometry.Dist(cutPoints[i].p, pl.Project(objectPoint)); if (distLoc < distCP) { distCP = distLoc; arcP2 = cutPoints[i].p; // Schnittpunkt schonmal merken } // arcP2 = cutPoints[i].p; // break; } } if (!Precision.IsEqual(arcP1, arcP2)) // runden war möglich { // Mittelwert zwischen dem Kurven // roundRadCalc = (Math.Abs(curve1_2D.Distance(pl.Project(radiusPoint))) + Math.Abs(curve2_2D.Distance(pl.Project(radiusPoint)))) / 2.0; // objectPoint = pl.ToGlobal(cutPoint.p); // merken für onDone, als Entscheidungskriterium arc.SetArcPlaneCenterStartEndPoint(base.ActiveDrawingPlane, arcCenter, arcP1, arcP2, pl, false); Ellipse arc1 = Ellipse.Construct(); arc1.SetArcPlaneCenterStartEndPoint(base.ActiveDrawingPlane, arcCenter, arcP1, arcP2, pl, true); if (Math.Abs(arc.SweepParameter) > Math.Abs(arc1.SweepParameter)) // es ist immer der kleinere Bogen! { arc = arc1; } arc.CopyAttributes(iCurve1 as IGeoObject); base.ActiveObject = arc; // merken base.FeedBack.AddSelected(arc); // darstellen return(true); } } } } // roundObject.HitCursor = CursorTable.GetCursor("RoundIn.cur"); return(false); }
private bool showLine() { ArrayList usable1Curves = new ArrayList(); ArrayList usable2Curves = new ArrayList(); ArrayList usable3Curves = new ArrayList(); Plane pl; Plane pl1; double mindist = double.MaxValue; int selSolLoc; if (tang1Curves == null) { return(false); } if (tang2Curves == null) { return(false); } // if (tang3Curves == null) return false; for (int i = 0; i < tang1Curves.Length; ++i) { for (int j = 0; j < tang2Curves.Length; ++j) { if (Curves.GetCommonPlane(tang1Curves[i], tang2Curves[j], out pl)) { if (tang3Curves == null) { return(true); // bei zwei bestimmten: sind in der gleichen Ebene } for (int k = 0; k < tang3Curves.Length; ++k) { if (Curves.GetCommonPlane(tang1Curves[i], tang3Curves[k], out pl1)) { if (Precision.IsEqual(pl, pl1)) { ICurve2D l2D1 = tang1Curves[i].GetProjectedCurve(pl); if (l2D1 is Path2D) { (l2D1 as Path2D).Flatten(); } ICurve2D l2D2 = tang2Curves[j].GetProjectedCurve(pl); if (l2D2 is Path2D) { (l2D2 as Path2D).Flatten(); } ICurve2D l2D3 = tang3Curves[k].GetProjectedCurve(pl); if (l2D3 is Path2D) { (l2D3 as Path2D).Flatten(); } GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, l2D2, l2D3, pl.Project(object1Point), pl.Project(object2Point), pl.Project(object3Point)); if (tangentPoints.Length > 0) { // eine gültige Linie ist gefunden usable1Curves.Add(tang1Curves[i]); // zur lokalen Liste zufügen usable2Curves.Add(tang2Curves[j]); // zur lokalen Liste zufügen usable3Curves.Add(tang3Curves[k]); // zur lokalen Liste zufügen for (int l = 0; l < tangentPoints.Length; l += 4) { double dist = Geometry.Dist(tangentPoints[l + 1], pl.Project(object1Point)) + Geometry.Dist(tangentPoints[l + 2], pl.Project(object2Point)) + Geometry.Dist(tangentPoints[l + 3], pl.Project(object3Point)); if (dist < mindist) { mindist = dist; selected1 = usable1Curves.Count - 1; // merken, welche Kurven die aktuell benutzten sind selected2 = usable2Curves.Count - 1; selected3 = usable3Curves.Count - 1; // selSol / 6 entspricht div 6, um einige Zeilen tiefer weitere 6 Möglichkeiten auswählen zu können // (/ 4) und (* 4), da pro Lösung vier Punkte geliefert werden int m = (l + 4 * ((Math.Abs(selSol) / 6) % (tangentPoints.Length / 4))) % tangentPoints.Length; selSolLoc = (Math.Abs(selSol) % 6) / 2; // liefert 0, 1, oder 2, "/2" um unten die Orientierung umschalten zu können center = tangentPoints[m]; arcRad = Geometry.Dist(tangentPoints[m + selSolLoc + 1], center); if ((Math.Abs(selSol) & 0x1) == 0) // 0 und 1 dienen zur Unterscheidung der Kreisbogenausrichtung { startAngle = new Angle(tangentPoints[m + selSolLoc + 1], center); endAngle = new Angle(tangentPoints[m + ((selSolLoc + 1) % 3) + 1], center); // "%3", also modulo 3, da der Index läuft: 2,3,1 } else { endAngle = new Angle(tangentPoints[m + selSolLoc + 1], center); startAngle = new Angle(tangentPoints[m + ((selSolLoc + 1) % 3) + 1], center); // "%3", also modulo 3, da der Index läuft: 2,3,1 } } } } if (mindist < double.MaxValue) { // base.MultiSolution = true; base.MultiSolutionCount = (tangentPoints.Length / 4) * 6; arc.SetArcPlaneCenterRadiusAngles(pl, pl.ToGlobal(center), arcRad, startAngle, new SweepAngle(startAngle, endAngle, arcDir)); base.ShowActiveObject = true; tang1Curves = (ICurve[])usable1Curves.ToArray(typeof(ICurve)); // überschreibt die eigentliche Liste und wird unten an den Sender zurückgeliefert tang2Curves = (ICurve[])usable2Curves.ToArray(typeof(ICurve)); // überschreibt die eigentliche Liste und wird unten an den Sender zurückgeliefert tang3Curves = (ICurve[])usable3Curves.ToArray(typeof(ICurve)); // überschreibt die eigentliche Liste und wird unten an den Sender zurückgeliefert return(true); } } } } } } } base.ShowActiveObject = false; base.MultiSolutionCount = 0; // base.MultiSolution = false; return(false); }
public override ICurve Make3dCurve(ICurve2D curve2d) { if (curve2d is Line2D l2d) { if (Math.Abs(Geometry.DistPL(GeoPoint2D.Origin, l2d.StartPoint, l2d.EndPoint)) < Precision.eps) { // a line through the center: this is a line on the surface return(Line.TwoPoints(PointAt(l2d.StartPoint), PointAt(l2d.EndPoint))); } else { // an ellipse (this is a very rare case) // this can certainly be optimized: take 5 points of the line, find the 3d positions, find a plane through the points // and calculate the ellipse from the points GeoPoint[] fp3d = new GeoPoint[5]; for (int i = 0; i < 5; i++) { fp3d[i] = PointAt(l2d.PointAt(i / 4.0)); } Ellipse elli = Ellipse.FromFivePoints(fp3d, false); if (elli != null) { return(elli); } } } else if (curve2d is Ellipse2D elli2d) { // includes EllipseArc2D if (Precision.IsEqual(elli2d.center, GeoPoint2D.Origin)) { // this is an ellipse in 3d GeoPoint[] fp3d = new GeoPoint[5]; double n = 5.0; if (elli2d is EllipseArc2D) { n = 4.0; } for (int i = 0; i < 5; i++) { fp3d[i] = PointAt(elli2d.PointAt(i / n)); } Ellipse elli = Ellipse.FromFivePoints(fp3d, !(elli2d is EllipseArc2D)); if (elli != null) { return(elli); } } } else if (curve2d is Circle2D circle2d) { // includes Arc2D if (Precision.IsEqual(circle2d.Center, GeoPoint2D.Origin)) { // this is an ellipse in 3d GeoPoint[] fp3d = new GeoPoint[5]; double n = 5.0; if (circle2d is Arc2D) { n = 4.0; } for (int i = 0; i < 5; i++) { fp3d[i] = PointAt(circle2d.PointAt(i / n)); } Ellipse elli = Ellipse.FromFivePoints(fp3d, !(circle2d is Arc2D)); if (elli != null) { return(elli); } } } return(base.Make3dCurve(curve2d)); }