private void input2DimCurvesChanged(CurveInput sender, ICurve SelectedCurve) { Plane pl; line2 = SelectedCurve as Line; if (Curves.GetCommonPlane(line1, line2, out pl)) { // Schnittpunkt der Linien GeoPoint2D dimC2D; if (Geometry.IntersectLL(pl.Project(line1.StartPoint), pl.Project(line1.EndPoint), pl.Project(line2.StartPoint), pl.Project(line2.EndPoint), out dimC2D)) { GeoPoint dimC = pl.ToGlobal(dimC2D); dim.SetPoint(0, dimC); // wegen der Optik: Hilfslinien konstruieren Line lineT = Line.Construct(); // lineT.SetTwoPoints(dimC,line1.StartPoint); lineT.SetTwoPoints(dimC, line1.PointAt(line1.PositionOf(objectPoint1))); // wegen der Optik: Hilfspunkt nahe Mittelpunkt konstruieren dim.SetPoint(1, lineT.PointAt(0.01)); // lineT.SetTwoPoints(dimC,line2.StartPoint); lineT.SetTwoPoints(dimC, line2.PointAt(line2.PositionOf(objectPoint2))); dim.SetPoint(2, lineT.PointAt(0.01)); dim.DimLineRef = base.CurrentMousePosition; base.ShowActiveObject = true; } } }
private bool Recalc() { Plane pl; GeoPoint2D lotPoint = new GeoPoint2D(0.0, 0.0); if (Curves.GetCommonPlane(distPoint, distCurve, out pl)) { ICurve2D curve_2D = distCurve.GetProjectedCurve(pl); // die 2D-Kurve if (curve_2D is Path2D) { (curve_2D as Path2D).Flatten(); } GeoPoint2D distPoint2D = pl.Project(distPoint); GeoPoint2D[] perpP = curve_2D.PerpendicularFoot(distPoint2D); // Lotpunkt(e) Kurve double distCP = double.MaxValue; for (int j = 0; j < perpP.Length; ++j) // Schleife über alle Lotpunkte Kurve { double distLoc = Geometry.Dist(perpP[j], distPoint2D); if (distLoc < distCP) { distCP = distLoc; lotPoint = perpP[j]; // Lotpunkt schonmal merken } } if (distCP < double.MaxValue) { feedBackLine.SetTwoPoints(distPoint, pl.ToGlobal(lotPoint)); if (!feedBackAdd) { base.FeedBack.Add(feedBackLine); feedBackAdd = true; } actualLength = Geometry.Dist(distPoint, pl.ToGlobal(lotPoint)); secondPoint = pl.ToGlobal(lotPoint); using (Frame.Project.Undo.ContextFrame(this)) { if (lengthProperty != null) { lengthProperty.SetLength(actualLength); } } return(true); } } if (feedBackAdd) { base.FeedBack.Remove(feedBackLine); feedBackAdd = false; } using (Frame.Project.Undo.ContextFrame(this)) { if (lengthProperty != null) { lengthProperty.SetLength(cancelLength); } } actualLength = 0; return(false); }
private void PerpFoot() { if (dimCurve != null) //falls in CurveInput (s.u.) ein Objekt getroffen war { Plane pl; double mindist = double.MaxValue; GeoPoint2D footPoint = new GeoPoint2D(0.0, 0.0); if (Curves.GetCommonPlane(dim.DimLineRef, dimCurve, out pl)) { ICurve2D c2D = dimCurve.GetProjectedCurve(pl); if (c2D is Path2D) { (c2D as Path2D).Flatten(); } GeoPoint2D[] perpPoints = c2D.PerpendicularFoot(pl.Project(dim.DimLineRef)); if (perpPoints.Length > 0) { // eine gültige Kurve ist gefunden for (int j = 0; j < perpPoints.Length; ++j) { double dist = Geometry.Dist(perpPoints[j], pl.Project(dim.DimLineRef)); if (dist < mindist) { mindist = dist; footPoint = perpPoints[j]; } } } } if (mindist < double.MaxValue) { // also: Fußpunkt gefunden dim.SetPoint(0, pl.ToGlobal(footPoint)); } } }
private bool Recalc() { double mindist = double.MaxValue; ICurve2D c1_2D; ICurve2D c2_2D; GeoPoint objectPoint = new GeoPoint(objectPoint1, objectPoint2); // die Mitte der Pickpunkte der zwei Objekte GeoPoint2D startPoint2D = new GeoPoint2D(0.0, 0.0); Plane pl; if (Curves.GetCommonPlane(intersectCurve1, intersectCurve2, out pl)) // die Kurven liegen in einer Ebene { c1_2D = intersectCurve1.GetProjectedCurve(pl); if (c1_2D is Path2D) { (c1_2D as Path2D).Flatten(); } c2_2D = intersectCurve2.GetProjectedCurve(pl); if (c2_2D is Path2D) { (c2_2D as Path2D).Flatten(); } GeoPoint2DWithParameter[] intersectPoints = c1_2D.Intersect(c2_2D); // die Schnittpunkte if (intersectPoints.Length > 0) { // nun den nächsten auswählen for (int j = 0; j < intersectPoints.Length; ++j) { double dist = Geometry.Dist(intersectPoints[j].p, pl.Project(objectPoint)); if (dist < mindist) { mindist = dist; startPoint2D = intersectPoints[j].p; } } } if (mindist < double.MaxValue) { actualPoint = pl.ToGlobal(startPoint2D); using (Frame.Project.Undo.ContextFrame(this)) { if (geoPointProperty != null) { geoPointProperty.SetGeoPoint(actualPoint); } } gPoint.Location = actualPoint; return(true); } } using (Frame.Project.Undo.ContextFrame(this)) { if (geoPointProperty != null) { geoPointProperty.SetGeoPoint(cancelPoint); } } actualPoint = cancelPoint; return(false); }
private bool input2DimCurves(CurveInput sender, ICurve[] dCurves, bool up) { // kommt nur drann, wenn schon eine Linie angeklickt wurde bool ok = false; objectPoint2 = base.CurrentMousePosition; base.ShowActiveObject = false; if (dCurves.Length > 0) { // zunächst: Nur alle Linien ausfiltern ArrayList usableCurves = new ArrayList(); for (int i = 0; i < dCurves.Length; ++i) { if (dCurves[i] is Line) { usableCurves.Add(dCurves[i]); // zur lokalen Liste zufügen } } dCurves = (ICurve[])usableCurves.ToArray(typeof(ICurve)); // überschreibt die eigentliche Liste und wird unten an den Sender zurückgeliefert if (dCurves.Length > 0) { // also: eine linie da! Plane pl; line2 = dCurves[0] as Line; if (Curves.GetCommonPlane(line1, line2, out pl)) { // Schnittpunkt der Linien GeoPoint2D dimC2D; if (Geometry.IntersectLL(pl.Project(line1.StartPoint), pl.Project(line1.EndPoint), pl.Project(line2.StartPoint), pl.Project(line2.EndPoint), out dimC2D)) { GeoPoint dimC = pl.ToGlobal(dimC2D); dim.SetPoint(0, dimC); // wegen der Optik: Hilfslinien konstruieren Line lineT = Line.Construct(); lineT.SetTwoPoints(dimC, line1.PointAt(line1.PositionOf(objectPoint1))); // lineT.SetTwoPoints(dimC,Geometry.DropPL(base.CurrentMousePosition,line1.StartPoint,line1.EndPoint)); // wegen der Optik: Hilfspunkt nahe Mittelpunkt konstruieren dim.SetPoint(1, lineT.PointAt(0.01)); lineT.SetTwoPoints(dimC, line2.PointAt(line2.PositionOf(objectPoint2))); // lineT.SetTwoPoints(dimC,Geometry.DropPL(base.CurrentMousePosition,line2.StartPoint,line2.EndPoint)); dim.SetPoint(2, lineT.PointAt(0.01)); dim.DimLineRef = base.CurrentMousePosition; base.ShowActiveObject = true; ok = true; } } } } if (up) { if (dCurves.Length == 0) { sender.SetCurves(dCurves, null); // ...die werden jetzt im ControlCenter dargestellt (nur bei up) } else { sender.SetCurves(dCurves, dCurves[0]); } } return(ok); }
private bool Recalc() { Plane pl; double distmin; GeoPoint2D p1, p2; if (Curves.GetCommonPlane(distCurve1, distCurve2, out pl)) { ICurve2D curve1_2D = distCurve1.GetProjectedCurve(pl); // die 2D-Kurve if (curve1_2D is Path2D) { (curve1_2D as Path2D).Flatten(); } ICurve2D curve2_2D = distCurve2.GetProjectedCurve(pl); // die 2D-Kurve if (curve2_2D is Path2D) { (curve2_2D as Path2D).Flatten(); } distmin = Curves2D.SimpleMinimumDistance(curve1_2D, curve2_2D, out p1, out p2); if (distmin > Precision.eps) { feedBackLine.SetTwoPoints(pl.ToGlobal(p1), pl.ToGlobal(p2)); if (!feedBackAdd) { base.FeedBack.Add(feedBackLine); feedBackAdd = true; } using (Frame.Project.Undo.ContextFrame(this)) { if (lengthProperty != null) { lengthProperty.SetLength(distmin); } } actualLength = distmin; return(true); } } if (feedBackAdd) { base.FeedBack.Remove(feedBackLine); feedBackAdd = false; } using (Frame.Project.Undo.ContextFrame(this)) { if (lengthProperty != null) { lengthProperty.SetLength(cancelLength); } } actualLength = 0; return(false); }
private bool showLine() { ICurve2D c1_2D; ICurve2D c2_2D; objectPoint = new GeoPoint(objectPoint1, objectPoint2); // die Mitte der Pickpunkte der zwei Objekte Plane pl; if (Curves.GetCommonPlane(tangCurve1, tangCurve2, out pl)) // die Kurven liegen in einer Ebene { c1_2D = tangCurve1.GetProjectedCurve(pl); if (c1_2D is Path2D) { (c1_2D as Path2D).Flatten(); } c2_2D = tangCurve2.GetProjectedCurve(pl); if (c2_2D is Path2D) { (c2_2D as Path2D).Flatten(); } GeoPoint2DWithParameter cutPoint; // der nächste der Schnittpunkte ist in cutPoint if (Curves2D.NearestPoint(c1_2D.Intersect(c2_2D), pl.Project(objectPoint), out cutPoint)) { base.MultiSolutionCount = 4; try { GeoVector2D v1 = c1_2D.DirectionAt(cutPoint.par1); // die Richtung im Schnittpunkt v1.Norm(); GeoVector2D v2 = c2_2D.DirectionAt(cutPoint.par2); // die Richtung im Schnittpunkt v2.Norm(); startPoint = pl.ToGlobal(cutPoint.p); endPoint = pl.ToGlobal(new GeoPoint2D(cutPoint.p, lineLength, (v1 + v2).Angle)); if (selectLine()) // die wahrscheinlichste der vier möglichen wählen { lengthInput.SetDistanceFromPoint(line.StartPoint); // die Basis für die Längenbestimmung base.ShowActiveObject = true; return(true); } } catch (GeoVectorException) { base.ShowActiveObject = false; base.MultiSolutionCount = 0; return(false); } } } base.ShowActiveObject = false; base.MultiSolutionCount = 0; return(false); }
private bool showDim() { if ((dimCurve == null) | (dim2Curve == null) | (dimCurve == dim2Curve)) { return(false); } Plane pl; if (Curves.GetCommonPlane(dimCurve, dim2Curve, out pl)) { ICurve2D l2D1 = dimCurve.GetProjectedCurve(pl); if (l2D1 is Path2D) { (l2D1 as Path2D).Flatten(); } ICurve2D l2D2 = dim2Curve.GetProjectedCurve(pl); if (l2D2 is Path2D) { (l2D2 as Path2D).Flatten(); } GeoPoint2D dim2DP1, dim2DP2, dimLoc; dimLoc = pl.Project(objectPoint); double dist = Curves2D.SimpleMinimumDistance(l2D1, l2D2, dimLoc, out dim2DP1, out dim2DP2); if (dist > 0) { // eine gültige Bemassung kann gemacht werden GeoPoint dimP1 = pl.ToGlobal(dim2DP1); GeoPoint dimP2 = pl.ToGlobal(dim2DP2); dim.DimLineDirection = new GeoVector(dimP1, dimP2); if (!dimLocationInput.Fixed) { dim.DimLineRef = new GeoPoint(dimP1, dimP2); } if (dim.PointCount == 0) { dim.AddPoint(dimP1); dim.AddPoint(dimP2); } else { dim.SetPoint(0, dimP1); dim.SetPoint(1, dimP2); } base.ShowActiveObject = true; return(true); } } base.ShowActiveObject = false; return(false); }
private bool showLine() { ArrayList usableCurves = new ArrayList(); // ArrayList usablePoints = new ArrayList(); double mindist = double.MaxValue; for (int i = 0; i < tangCurves.Length; ++i) { Plane pl; int solCount = 0; if (Curves.GetCommonPlane(startPoint, tangCurves[i], out pl)) { ICurve2D l2D = tangCurves[i].GetProjectedCurve(pl); if (l2D is Path2D) { (l2D as Path2D).Flatten(); } GeoPoint2D[] tangentPoints = l2D.TangentPoints(pl.Project(startPoint), pl.Project(objectPoint)); //!!! if (tangentPoints.Length > 0) { // eine gültige Kurve ist gefunden solCount = tangentPoints.Length; usableCurves.Add(tangCurves[i]); // zur lokalen Liste zufügen for (int j = 0; j < tangentPoints.Length; ++j) { double dist = Geometry.Dist(tangentPoints[j], pl.Project(objectPoint)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist // die Punkte werden als sortiert erwartet!! Hier nur über modulo (%) den Index bestimmen endPoint = tangentPoints[Math.Abs(selSol) % tangentPoints.Length]; } } } } if (mindist < double.MaxValue) { base.MultiSolutionCount = solCount; line.SetTwoPoints(startPoint, pl.ToGlobal(endPoint)); tangCurves = (ICurve[])usableCurves.ToArray(typeof(ICurve)); // überschreibt die eigentliche Liste und wird unten an den Sender zurückgeliefert base.ShowActiveObject = true; return(true); } } base.MultiSolutionCount = 0; line.SetTwoPoints(startPoint, objectPoint); base.ShowActiveObject = true; return(false); }
private bool showLine() { Plane pl; if (Curves.GetCommonPlane(throughPoint, iCurve, out pl)) { ICurve2D l2D = iCurve.GetProjectedCurve(pl); if (l2D is Path2D) { (l2D as Path2D).Flatten(); } double dist = l2D.Distance(pl.Project(throughPoint)); // System.Diagnostics.Trace.WriteLine(dist.ToString()); ICurve2D l2DP = l2D.Parallel(-dist, false, 0.0, 0.0); line.SetTwoPoints(pl.ToGlobal(l2DP.StartPoint), pl.ToGlobal(l2DP.EndPoint)); base.ShowActiveObject = true; return(true); } base.ShowActiveObject = false; return(false); }
private bool GetCenter(out GeoPoint c) { Plane pl; c = dimP4; Line line1 = Line.Construct(); line1.SetTwoPoints(dimP1, dimP2); Line line2 = Line.Construct(); line2.SetTwoPoints(dimP3, dimP4); if (Curves.GetCommonPlane(line1, line2, out pl)) { GeoPoint2D dimC2D; if (Geometry.IntersectLL(pl.Project(dimP1), pl.Project(dimP2), pl.Project(dimP3), pl.Project(dimP4), out dimC2D)) { c = pl.ToGlobal(dimC2D); return(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 rotateOrg(bool openDraw) { if (selectedObjectsList == null || selectedObjectsList.Count == 0) { return(false); } IGeoObject selectedObject = null; blk = Block.Construct(); // as feedback object if (base.ActiveObject != null) { blk.CopyAttributes(base.ActiveObject); } // der block wird das neue aktive Objekt, er muss die Attribute tragen, weil sie später // wieder von ihm verlangt werden Boolean success = false; GeoPoint axisPointSav = axisPoint; GeoVector axisVectorSav = axisVector; updateOptional(); if (selectedObjectsList.Count > 1) { // maybe there are several curves in the list, then we try to make a path // and use only this path. No mixture of faces and paths possible List <ICurve> crvs = new List <ICurve>(); for (int i = 0; i < selectedObjectsList.Count; i++) { if (selectedObjectsList[i] is ICurve crv) { crvs.Add(crv); } } if (crvs.Count > 1) { Path path = Path.FromSegments(crvs, false); if (path != null) { selectedObjectsList.Clear(); selectedObjectsList.Add(path); } } } for (int i = 0; i < selectedObjectsList.Count; i++) { IGeoObject objectToRotate = null; // lokaler Merker geoObjectOrgList[i] = selectedObject; // zum Weglöschen des Originals in onDone selectedObject = selectedObjectsList[i]; ownerList[i] = selectedObject.Owner; // owner merken für löschen pathCreatedFromModelList[i] = null; shapeList[i] = null; if ((selectedObject is Face) || (selectedObject is Shell)) { // nur kopieren objectToRotate = selectedObject.Clone(); } else { if (selectedObject is ICurve selCurve) { Path p = null; if (!selCurve.IsClosed) { // trying to rotate an open curve: if the axis and the curve have a commonn plane close a path with the perpendicular foot points and axis segment Line axisLine = Line.TwoPoints(axisPoint, axisPoint + axisVector); if (Curves.GetCommonPlane(new ICurve[] { selCurve, axisLine }, out Plane commonPlane)) { Line l1 = Line.TwoPoints(selCurve.EndPoint, Geometry.DropPL(selCurve.EndPoint, axisPoint, axisVector)); Line l2 = Line.TwoPoints(Geometry.DropPL(selCurve.StartPoint, axisPoint, axisVector), selCurve.StartPoint); Line l3 = Line.TwoPoints(l1.EndPoint, l2.StartPoint); List <ICurve> closedPath = new List <ICurve>(); closedPath.Add(selCurve); if (l1.Length > Precision.eps) { closedPath.Add(l1); } if (l3.Length > Precision.eps) { closedPath.Add(l3); } if (l2.Length > Precision.eps) { closedPath.Add(l2); } p = Path.FromSegments(closedPath, true); // should always work p.Flatten(); } } else { p = Path.FromSegments(new ICurve[] { selCurve }, true); } if (p == null) { continue; // no path constructed } if ((p as ICurve).GetSelfIntersections().Length > 0) { continue; // not possible } if (!p.IsClosed) { continue; } // make a face from the closed pathe objectToRotate = Make3D.MakeFace(p, Frame.Project, true); } } if (objectToRotate != null) { // also was geeignetes dabei //if (angleOffsetRotation != 0.0) //{ // ModOp m = ModOp.Rotate(axisPoint, axisVector, new SweepAngle(angleOffsetRotation)); // iGeoObjectTemp.Modify(m); //} double sw = angleRotation; if (sw == 0.0) { sw = Math.PI * 2.0; } // IGeoObject shape = Make3D.MakeRevolution(iGeoObjectTemp, axisPoint, axisVector, sw, Frame.Project); IGeoObject shape = Make3D.Rotate(objectToRotate, new Axis(axisPoint, axisVector), sw, angleOffsetRotation, Frame.Project); if (shape != null) { shape.CopyAttributes(blk); shapeList[i] = shape; // fertiger Körper in shapeList blk.Add(shape); // resulting object base.FeedBack.AddSelected(objectToRotate); // zum Markieren des Ursprungsobjekts success = true; } } } axisPoint = axisPointSav; // im Fall nicht geschlossener Pfad und nichts bestimmt, werden diese Parameter oben verstellt axisVector = axisVectorSav; if (success) { base.ActiveObject = blk; // darstellen base.ShowActiveObject = true; return(true); } else { updateOptional(); base.ShowActiveObject = false; base.FeedBack.ClearSelected(); 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); }
private bool showLine() { ArrayList usableCurves = new ArrayList(); // lokales Array, das die gültigen Kurven sammelt double mindist = double.MaxValue; for (int i = 0; i < tangCurves.Length; ++i) { Plane pl; double lineAngle; if (Curves.GetCommonPlane(objectPoint, tangCurves[i], out pl)) { ICurve2D l2D = tangCurves[i].GetProjectedCurve(pl); if (l2D is Path2D) { (l2D as Path2D).Flatten(); } lineAngle = pl.Project(lineDir).Angle; // 2D-Winkel aus der Richtung erzeugen GeoPoint2D[] tangentPoints = l2D.TangentPointsToAngle(lineAngle, pl.Project(objectPoint)); if (tangentPoints.Length > 0) { // eine gültige Kurve ist gefunden usableCurves.Add(tangCurves[i]); for (int j = 0; j < tangentPoints.Length; ++j) { double dist = Geometry.Dist(tangentPoints[j], pl.Project(objectPoint)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist startPoint2D = tangentPoints[j]; } } } } if (mindist < double.MaxValue) { if (!linePositionMiddle) { startPoint = pl.ToGlobal(startPoint2D); endPoint = startPoint + lineLength * lineDir; } else { startPoint = pl.ToGlobal(startPoint2D) - (lineLength / 2.0) * lineDir; endPoint = pl.ToGlobal(startPoint2D) + (lineLength / 2.0) * lineDir; } line.SetTwoPoints(startPoint, endPoint); tangCurves = (ICurve[])usableCurves.ToArray(typeof(ICurve)); // tangCurves wird mit den gültigen überschrieben und unten zur Anzeige zurückgegeben an den Sender base.BasePoint = pl.ToGlobal(startPoint2D); // base.BasePoint = line.StartPoint; return(true); } } // hier Prototyp-Darstellung: if (!linePositionMiddle) { startPoint = base.BasePoint; endPoint = startPoint + lineLength * lineDir; } else { startPoint = base.BasePoint - (lineLength / 2.0) * lineDir; endPoint = base.BasePoint + (lineLength / 2.0) * lineDir; } // startPoint = base.BasePoint; // endPoint = startPoint+lineLength*lineDir; line.SetTwoPoints(startPoint, endPoint); return(false); }
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 showLine() { ArrayList usable1Curves = new ArrayList(); ArrayList usable2Curves = new ArrayList(); Plane pl; double mindist = double.MaxValue; if (tang1Curves == null) { return(false); } if (tang2Curves == 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 (Precision.IsPointOnPlane(circlePoint, pl)) { 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(); } // der Trick, den OpenCascade mitmacht: 3. Kreis mit Radius 0!! ICurve2D l2D3 = new Circle2D(pl.Project(circlePoint), 0.0); GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, l2D2, l2D3, pl.Project(object1Point), pl.Project(object2Point), pl.Project(circlePoint)); if (tangentPoints.Length > 0) { // eine gültige Lösung ist gefunden usable1Curves.Add(tang1Curves[i]); // zur lokalen Liste zufügen usable2Curves.Add(tang2Curves[j]); // zur lokalen Liste zufügen for (int l = 0; l < tangentPoints.Length; l += 4) { // mittlerer Abstand zu den Klickpunkten als Ausscheidungskriterium 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(circlePoint)); if (dist < mindist) { mindist = dist; selected1 = usable1Curves.Count - 1; // merken, welche Kurven die aktuell benutzten sind selected2 = usable2Curves.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 base.ShowActiveObject = true; return(true); } } } } } base.ShowActiveObject = false; base.MultiSolutionCount = 0; // base.MultiSolution = false; 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); }
private bool showLine() { ArrayList usableCurves = new ArrayList(); ArrayList usable2Curves = new ArrayList(); double mindist = double.MaxValue; if (tangCurves == null) { return(false); } if (tang2Curves == null) { return(false); } for (int i = 0; i < tangCurves.Length; ++i) { for (int j = 0; j < tang2Curves.Length; ++j) { Plane pl; if (Curves.GetCommonPlane(tangCurves[i], tang2Curves[j], out pl)) { ICurve2D l2D1 = tangCurves[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(); } GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, l2D2, circRad); if (tangentPoints.Length > 0) { // eine gültige Linie ist gefunden usableCurves.Add(tangCurves[i]); // zur lokalen Liste zufügen usable2Curves.Add(tang2Curves[j]); // zur lokalen Liste zufügen for (int k = 0; k < tangentPoints.Length; k += 3) { double dist = Geometry.Dist(tangentPoints[k + 1], pl.Project(objectPoint)) + Geometry.Dist(tangentPoints[k + 2], pl.Project(object2Point)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist selected2 = usable2Curves.Count - 1; // merken, welche Kurve die aktuell benutzte ist // (/ 3) und (* 3), da pro Lösung drei Punkte geliefert werden int l = (k + 3 * (Math.Abs(selSol) % (tangentPoints.Length / 3))) % tangentPoints.Length; center = tangentPoints[l]; } } } if (mindist < double.MaxValue) { circRadCalc = (Math.Abs(l2D1.Distance(pl.Project(radiusPoint))) + Math.Abs(l2D2.Distance(pl.Project(radiusPoint)))) / 2.0; // base.MultiSolution = true; base.MultiSolutionCount = tangentPoints.Length / 3; circ.SetCirclePlaneCenterRadius(pl, pl.ToGlobal(center), circRad); tangCurves = (ICurve[])usableCurves.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 base.ShowActiveObject = true; return(true); } } } } base.MultiSolutionCount = 0; // base.MultiSolution = false; base.ShowActiveObject = false; return(false); }
private bool showRound() { // jetzt werden die Rundparameter bestimmt Plane pl; try { if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl)) { bool rndPos = false; // Runden möglich GeoPoint2D arcP1 = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcP2 = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcP1Loc = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcP2Loc = 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(); } // ist beim menrfachrunden nicht nötig!! // hier die Schnittpunkte bestimmen und den ObjectPoint auf den nächsten Schnittpunt setzen // GeoPoint2DWithParameter[] intersectPoints = curve1_2D.Intersect(curve2_2D); // GeoPoint2D objectPoint2D = new GeoPoint2D(0.0,0.0); // double distS = double.MaxValue; // Entfernung des Pickpunkts zu den Schnittpunkten // for (int i=0; i< intersectPoints.Length; ++i) // macht hier wenig Sinn, schadet aber auch nicht // { // macht hier wenig Sinn, schadet aber auch nicht, Kompatibilität zum einfachrunden // double distLoc = Geometry.dist(intersectPoints[i].p,pl.Project(objectPoint)); // if (distLoc < distS) // { // distS = distLoc; // objectPoint2D = intersectPoints[i].p; // Pickpunkt merken // } // } // statt der Berechnung oben: Auswahlpunkt ist der gemeinsame Punkt der beiden Kurven!! GeoPoint2D objectPoint2D = curve1_2D.EndPoint; 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; // bei mehfachrunden nicht nötig, da alle aneinanderhängen, also nur reale Schnittpunkte! // double locPar; // für den Fall: virtueller Schnittpunkt die Parametergrenzen anpassen // locPar = curve1_2D.PositionOf(objectPoint2D); // position des Schnittpunktes auf der Kurve1 // if ( locPar > 1.0) locmax1 = locPar; // if ( locPar < 0.0) locmin1 = locPar; // locPar = curve2_2D.PositionOf(objectPoint2D); // position des Schnittpunktes auf der Kurve2 // if ( locPar > 1.0) locmax2 = locPar; // if ( locPar < 0.0) locmin2 = locPar; // die Parallelen links und rechts der 2 Kurven ICurve2D P1L1 = curve1_2D.Parallel(roundRad, false, 0.0, 0.0); ICurve2D P1L2 = curve1_2D.Parallel(-roundRad, false, 0.0, 0.0); ICurve2D P2L1 = curve2_2D.Parallel(roundRad, false, 0.0, 0.0); ICurve2D P2L2 = curve2_2D.Parallel(-roundRad, false, 0.0, 0.0); // nun alle mit allen schneiden und Schnittpunkte (=evtl. Mittelpunkte des Bogens) merken ArrayList centers = new ArrayList(); centers.AddRange(P1L1.Intersect(P2L1)); centers.AddRange(P1L1.Intersect(P2L2)); centers.AddRange(P1L2.Intersect(P2L1)); centers.AddRange(P1L2.Intersect(P2L2)); GeoPoint2DWithParameter[] centerPoints = (GeoPoint2DWithParameter[])centers.ToArray(typeof(GeoPoint2DWithParameter)); GeoPoint2D[] perpP; // Lotfusspunkte double loc; // location des schnittpunktes der parallelen auf der Kurve double distCP; // Entfernung von der Ecke für Fusspunkte double distCS = double.MaxValue; // Entfernung von der Ecke für Schnittpunkte bool ok1, ok2; // der gesuchte Schnittpunkt hat einen realen Lotfusspunkt auf beiden Kurven und den Abstand roundRad von diesen for (int i = 0; i < centerPoints.Length; ++i) // Schleife über alle Schnittpunkte { ok1 = false; ok2 = false; perpP = curve1_2D.PerpendicularFoot(centerPoints[i].p); // Lotpunkt(e) Kurve 1 distCP = double.MaxValue; for (int j = 0; j < perpP.Length; ++j) // Schleife über alle Lotpunkte Kurve 1 { loc = curve1_2D.PositionOf(perpP[j]); // der Parameter des j. Lotpunktes auf Kurve1 // der Parameter muss innerhalb der Kurve sein und der Abstand = roundRad if ((loc >= locmin1) & (loc <= locmax1) & (Math.Abs(Geometry.Dist(perpP[j], centerPoints[i].p) - roundRad) < Precision.eps)) { double distLoc = Geometry.Dist(perpP[j], objectPoint2D); if (distLoc < distCP) { distCP = distLoc; arcP1Loc = perpP[j]; // Lotpunkt schonmal merken } ok1 = true; } } if (ok1) // also was gefunden oben, jetzt dasselbe mit Kurve 2 { perpP = curve2_2D.PerpendicularFoot(centerPoints[i].p); // Lotpunkt(e) Kurve 2 distCP = double.MaxValue; for (int j = 0; j < perpP.Length; ++j) // Schleife über alle Lotpunkte Kurve 2 { loc = curve2_2D.PositionOf(perpP[j]); // der Parameter des j. Lotpunktes auf Kurve2 // der Parameter muss innerhalb der Kurve sein und der Abstand = roundRad if ((loc >= locmin2) & (loc <= locmax2) & (Math.Abs(Geometry.Dist(perpP[j], centerPoints[i].p) - roundRad) < Precision.eps)) { double distLoc = Geometry.Dist(perpP[j], objectPoint2D); if (distLoc < distCP) { distCP = distLoc; arcP2Loc = perpP[j]; // Lotpunkt schonmal merken } ok2 = true; } } } if (ok2) { // falls mehrere Schnittpunkte alle Bedingungen erfüllen: Den nächsten nehmen! double distLoc = Geometry.Dist(centerPoints[i].p, objectPoint2D); if (distLoc < distCS) { distCS = distLoc; // jetzt merken arcCenter = centerPoints[i].p; arcP1 = arcP1Loc; arcP2 = arcP2Loc; rndPos = true; } } } if (rndPos && !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(objectPoint2D); // merken als Entscheidungskriterium, ist hier immer der Schnittpunkt Ellipse arc = Ellipse.Construct(); Ellipse arc1 = Ellipse.Construct(); arc.SetArcPlaneCenterStartEndPoint(base.ActiveDrawingPlane, arcCenter, arcP1, arcP2, pl, false); 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); if (iCurve1.PositionOf(objectPoint) > 0.5) { iCurve1.Trim(0.0, iCurve1.PositionOf(arc.StartPoint)); } else { iCurve1.Trim(iCurve1.PositionOf(arc.StartPoint), 1.0); } if (iCurve2.PositionOf(objectPoint) > 0.5) { iCurve2.Trim(0.0, iCurve2.PositionOf(arc.EndPoint)); } else { iCurve2.Trim(iCurve2.PositionOf(arc.EndPoint), 1.0); } if (iCurve1.Length > Precision.eps) { blk.Add(iCurve1 as IGeoObject); // base.FeedBack.AddSelected(iCurve1 as IGeoObject); // darstellen } blk.Add(arc); // base.FeedBack.AddSelected(arc); // darstellen iCurve1 = iCurve2; // getrimmte Curve2 als Grundlage zur nächsten Berechnung return(true); } } } catch (ApplicationException e) { return(false); } blk.Add(iCurve1 as IGeoObject); // unveränderte 1. Kurve zufügen, da kein Runden möglich // base.FeedBack.AddSelected(iCurve1 as IGeoObject); // darstellen iCurve1 = iCurve2; // unveränderte Curve2 als Grundlage zur nächsten Berechnung return(false); }
private void SetDimLocation(GeoPoint p) { // der Lagepunkt der Bemassung dim.DimLineRef = p; // kommt am Anfang wohl dran, deshalb diese Abfrage: if (curveInput.Fixed & curve2Input.Fixed) { Plane pl; if (Curves.GetCommonPlane(line1, line2, out pl)) { GeoVector v1, v2; if (line1.PositionOf(objectPoint1) < line1.PositionOf(dim.GetPoint(0))) // der Pickpunkt entscheidet { v1 = new GeoVector(dim.GetPoint(0), line1.StartPoint); // Mittelpunkt-Linie1 } else { v1 = new GeoVector(dim.GetPoint(0), line1.EndPoint); // Mittelpunkt-Linie1 } if (!v1.IsNullVector()) { v1.Norm(); } if (line2.PositionOf(objectPoint2) < line2.PositionOf(dim.GetPoint(0))) // der Pickpunkt entscheidet { v2 = new GeoVector(dim.GetPoint(0), line2.StartPoint); // Mittelpunkt-Linie2 } else { v2 = new GeoVector(dim.GetPoint(0), line2.EndPoint); // Mittelpunkt-Linie2 } if (!v2.IsNullVector()) { v2.Norm(); } // umschaltung auf die inverse Bemaßung, abhängig vom Lagepunkt p int ind1 = 1; // Umschaltindices für dimPoint (s.u.) int ind2 = 2; Ellipse arc = Ellipse.Construct(); // Kreisbogen der Bemassung nachbilden arc.SetArcPlaneCenterStartEndPoint(base.ActiveDrawingPlane, pl.Project(dim.GetPoint(0)), pl.Project(dim.GetPoint(0) + Geometry.Dist(dim.GetPoint(0), p) * v1), pl.Project(dim.GetPoint(0) + Geometry.Dist(dim.GetPoint(0), p) * v2), pl, true); if ((arc.PositionOf(p) > 1) || (arc.PositionOf(p) < 0)) // p ausserhalb, also drehen { ind1 = 2; ind2 = 1; } // nun die Berechnung so, dass die Hilfslinien nicht auf der Linie laufen, sondern nur ausserhalb GeoPoint2D[] cutPoints; // Schnittpunkt Linie1 und Kreis um Mittelpunkt durch p cutPoints = Geometry.IntersectLC(pl.Project(dim.GetPoint(0)), pl.Project(dim.GetPoint(0) + v1), pl.Project(dim.GetPoint(0)), Geometry.Dist(dim.GetPoint(0), p)); GeoPoint pLoc = GeoPoint.Origin; if (cutPoints.Length == 1) { pLoc = pl.ToGlobal(cutPoints[0]); } else if (cutPoints.Length > 1) { // den nächsten zum Pickpunkt nehmen if (Geometry.Dist(pl.ToGlobal(cutPoints[0]), objectPoint1) < Geometry.Dist(pl.ToGlobal(cutPoints[1]), objectPoint1)) { pLoc = pl.ToGlobal(cutPoints[0]); } else { pLoc = pl.ToGlobal(cutPoints[1]); } } double distLoc = line1.PositionOf(pLoc); // die Position auf der Linie if (distLoc < 0) { dim.SetPoint(ind1, line1.StartPoint); } else { if (distLoc > 1) { dim.SetPoint(ind1, line1.EndPoint); } else { dim.SetPoint(ind1, pLoc); // keine Hilfslinie innerhalb der Linie } } // Schnittpunkt Linie2 und Kreis um Mittelpunkt durch p cutPoints = Geometry.IntersectLC(pl.Project(dim.GetPoint(0)), pl.Project(dim.GetPoint(0) + v2), pl.Project(dim.GetPoint(0)), Geometry.Dist(dim.GetPoint(0), p)); if (cutPoints.Length == 1) { pLoc = pl.ToGlobal(cutPoints[0]); } else {// den nächsten zum Pickpunkt nehmen if (Geometry.Dist(pl.ToGlobal(cutPoints[0]), objectPoint2) < Geometry.Dist(pl.ToGlobal(cutPoints[1]), objectPoint2)) { pLoc = pl.ToGlobal(cutPoints[0]); } else { pLoc = pl.ToGlobal(cutPoints[1]); } } distLoc = line2.PositionOf(pLoc); // die Position auf der Linie if (distLoc < 0) { dim.SetPoint(ind2, line2.StartPoint); } else { if (distLoc > 1) { dim.SetPoint(ind2, line2.EndPoint); } else { dim.SetPoint(ind2, pLoc); // keine Hilfslinie innerhalb der Linie } } } } }
private void FindShape() { // wird in einem zweiten Thread aufgerufen. Ob es Probleme macht, dass von dieser // Methode ausgehend indirekt OpenCascade verwendet wird? Um zu verhindern, dass // gleichzeitig mehrere Methoden von OpenCascade laufen müsste man ein "lock" mit einem // globalen Objekt der OpenCascade Bibliothek machen... try { Frame.ActiveView.Canvas.Cursor = "WaitCursor"; GeoPoint p = base.CurrentMousePosition; foundOnPlane = CurrentMouseView.Projection.ProjectionPlane; // bei mehreren Fenstern so nicht gut!!! GeoPoint2D onPlane = foundOnPlane.Project(p); // hier müsste man irgendwie erst wenig picken und wenn nix geht dann immer mehr BoundingRect pickrect = new BoundingRect(onPlane, base.WorldViewSize, base.WorldViewSize); Set <Layer> visibleLayers = null; if (Frame.ActiveView is ModelView) { visibleLayers = new Set <Layer>((Frame.ActiveView as ModelView).GetVisibleLayers()); } #if !WEBASSEMBLY else if (Frame.ActiveView is GDI2DView) { visibleLayers = new Set <Layer>((Frame.ActiveView as GDI2DView).VisibleLayers.Checked); } #endif GeoObjectList l = Frame.ActiveView.Model.GetObjectsFromRect(pickrect, CurrentMouseView.Projection, visibleLayers, PickMode.normal, Frame.Project.FilterList); // Problem: ein großese Rechteck, welches weit über pickrect hinausgeht hat Inseln, die nicht im pickrect liegen // Diese werden nicht gefunden. Deshalb hier nochmal das pickrect ggf. erweitern pickrect = l.GetExtent(CurrentMouseView.Projection, true, false); // l = Frame.ActiveView.ProjectedModel.GetObjectsFromRect(pickrect, null); l = Frame.ActiveView.Model.GetObjectsFromRect(pickrect, CurrentMouseView.Projection, visibleLayers, PickMode.normal, Frame.Project.FilterList); l.DecomposeBlocks(false); // l.Reduce(Frame.Project.FilterList); // FilterList jetzt schon beim Picken // CompoundShape cs = CompoundShape.CreateFromConnectedList(l, foundOnPlane, onPlane, l.GetExtent().Size * 1e-6, mode); CompoundShape cs = null; if (cs == null) { CurveGraph cg = CurveGraph.CrackCurves(l, foundOnPlane, l.GetExtent().Size * 1e-6); // gap eine Ordnung größer als Precision if (cg != null) { cs = cg.CreateCompoundShape(true, onPlane, mode, false); #if DEBUG if (cs == null) { cg = CurveGraph.CrackCurves(l, foundOnPlane, l.GetExtent().Size * 1e-6); // gap eine Ordnung größer als Precision cs = cg.CreateCompoundShape(true, onPlane, mode, false); } #endif } else { cg = CurveGraph.CrackCurves(l, foundOnPlane, l.GetExtent().Size * 1e-6); // gap eine Ordnung größer als Precision } } if (cs != null) { Plane shapesPlane; Plane pln; if (cs != null) { // das BeginInvoke synchronisiert mit den MouseMessages, d.h. // OnShapeFound wird nur aufgerufen, wenn alle Messages // abgearbeitet sind, er also nicht in irgendeiner anderen // Methode dieser Klasse steckt. Denn in OnShapeFound wird // ActiveObject gesetzt und das geht nur synchron mit dem Control. if (Curves.GetCommonPlane(cs.Curves3d(), out shapesPlane)) { //cs = cs.Project(foundOnPlane, shapesPlane); pln = shapesPlane; } else { pln = CurrentMouseView.Projection.DrawingPlane; } if (debug) { OnShapeFound(cs, pln, p); } else { OnShapeFound(cs, pln, p); } } } findShapeIsRunning = false; } catch (ThreadAbortException) { findShapeIsRunning = false; } catch (System.Exception e) { string dbg = e.Message; findShapeIsRunning = false; } finally { // aus welchen Gründen könnte er hier rausfliegen??? findShapeIsRunning = false; } }
private bool showLine() { ArrayList usableCurves = new ArrayList(); ArrayList usable2Curves = new ArrayList(); double mindist = double.MaxValue; double arcRadLoc; if (tangCurves == null) { return(false); } if (tang2Curves == null) { return(false); } // if (!radInput.Fixed) arcRadLoc = Math.Max(arcRad,Geometry.dist(objectPoint,object2Point)/2); // else arcRadLoc = arcRad; arcRadLoc = arcRad; for (int i = 0; i < tangCurves.Length; ++i) { for (int j = 0; j < tang2Curves.Length; ++j) { Plane pl; if (Curves.GetCommonPlane(tangCurves[i], tang2Curves[j], out pl)) { ICurve2D l2D1 = tangCurves[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(); } GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, l2D2, arcRadLoc); if (tangentPoints.Length > 0) { // eine gültige Linie ist gefunden usableCurves.Add(tangCurves[i]); // zur lokalen Liste zufügen usable2Curves.Add(tang2Curves[j]); // zur lokalen Liste zufügen for (int k = 0; k < tangentPoints.Length; k += 3) { double dist = Geometry.Dist(tangentPoints[k + 1], pl.Project(objectPoint)) + Geometry.Dist(tangentPoints[k + 2], pl.Project(object2Point)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist selected2 = usable2Curves.Count - 1; // merken, welche Kurve die aktuell benutzte ist // die Punkte werden als sortiert erwartet!! Hier nur über modulo (%) den Index bestimmen // selSol / 2 shifted nach rechts, um 3 Zeilen tiefer weitere Möglichkeiten auswählen zu können // (/ 3) und (* 3), da pro Lösung drei Punkte geliefert werden int l = (k + 3 * ((Math.Abs(selSol) / 2) % (tangentPoints.Length / 3))) % tangentPoints.Length; center = tangentPoints[l]; if ((Math.Abs(selSol) & 0x1) == 0) // 0 und 1 dienen zur Unterscheidung der Kreisbogenausrichtung { startAngle = new Angle(tangentPoints[l + 1], center); endAngle = new Angle(tangentPoints[l + 2], center); } else { startAngle = new Angle(tangentPoints[l + 2], center); endAngle = new Angle(tangentPoints[l + 1], center); } } } } if (mindist < double.MaxValue) { arcRadCalc = (Math.Abs(l2D1.Distance(pl.Project(radiusPoint))) + Math.Abs(l2D2.Distance(pl.Project(radiusPoint)))) / 2.0; // base.MultiSolution = true; base.MultiSolutionCount = (tangentPoints.Length / 3) * 2; if (base.ActiveObject == null) { base.ActiveObject = arc; } // if (Math.Abs(new SweepAngle(startAngle,endAngle,arcDir)) > (Math.Abs(new SweepAngle(endAngle,startAngle,!arcDir)))) // arc.SetArcPlaneCenterRadiusAngles(base.ActiveDrawingPlane,pl.ToGlobal(center),arcRadLoc,startAngle,new SweepAngle(startAngle,endAngle,arcDir)); arc.SetArcPlaneCenterRadiusAngles(pl, pl.ToGlobal(center), arcRadLoc, startAngle, new SweepAngle(startAngle, endAngle, arcDir)); tangCurves = (ICurve[])usableCurves.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 base.ShowActiveObject = true; return(true); } } } } base.ShowActiveObject = false; // base.MultiSolution = false; base.MultiSolutionCount = 0; return(false); }
private bool showLine() { ArrayList usableCurves = new ArrayList(); ArrayList usable2Curves = new ArrayList(); double mindist = double.MaxValue; for (int i = 0; i < tangCurves.Length; ++i) { for (int j = 0; j < tang2Curves.Length; ++j) { Plane pl; if (Curves.GetCommonPlane(tangCurves[i], tang2Curves[j], out pl)) { ICurve2D l2D1 = tangCurves[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(); } GeoPoint2D[] tangentPoints = Curves2D.TangentLines(l2D1, l2D2); if (tangentPoints.Length > 0) { // eine gültige Linie ist gefunden usableCurves.Add(tangCurves[i]); // zur lokalen Liste zufügen usable2Curves.Add(tang2Curves[j]); // zur lokalen Liste zufügen for (int k = 0; k < tangentPoints.Length; k += 2) { double dist = Geometry.Dist(tangentPoints[k], pl.Project(objectPoint)) + Geometry.Dist(tangentPoints[k + 1], pl.Project(object2Point)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist selected2 = usable2Curves.Count - 1; // merken, welche Kurve die aktuell benutzte ist // die Punkte werden als sortiert erwartet!! Hier nur über modulo (%) den Index bestimmen int l = (k + 2 * (Math.Abs(selSol) % (tangentPoints.Length / 2))) % tangentPoints.Length; startPoint = tangentPoints[l]; endPoint = tangentPoints[l + 1]; } } } if (mindist < double.MaxValue) { // base.MultiSolution = true; base.MultiSolutionCount = tangentPoints.Length / 2; base.ShowActiveObject = true; line.SetTwoPoints(pl.ToGlobal(startPoint), pl.ToGlobal(endPoint)); tangCurves = (ICurve[])usableCurves.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 return(true); } } } } base.ShowActiveObject = false; base.MultiSolution = false; 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; 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 bool showObject() { base.FeedBack.ClearSelected(); base.ActiveObject = null; double[] cutPlace; ICurve2D c2d = iCurve.GetProjectedCurve(CurrentMouseView.Projection.ProjectionPlane); GeoPoint2D op2d = CurrentMouseView.Projection.ProjectUnscaled(objectPoint); lowerEnd = (c2d.PositionOf(op2d) < 0.5); // im 2D überprüfen, in 3D ist objectPoint möglicherweise weit von iCurve entfernt // bool lowerEnd = (iCurve.PositionOf(objectPoint)< 0.5); ProjectedModel.IntersectionMode cutMode; bool realCut; if (lowerEnd) { cutMode = ProjectedModel.IntersectionMode.StartExtension; } else { cutMode = ProjectedModel.IntersectionMode.EndExtension; } // if (expandSourceObject.Fixed) ICurve[] targetCurves = null; if (sourceCurve != null) { cutPlace = Curves.Intersect(iCurve, sourceCurve, false); } else { cutPlace = base.Frame.ActiveView.ProjectedModel.GetIntersectionParameters(iCurve, cutMode, out targetCurves); } if (cutPlace.Length > 0) { realCut = false; for (int i = 0; i < cutPlace.Length; ++i) { if (distToCurve.Length == 0) { if (cutPlace[i] < -1e-8 || cutPlace[i] > 1 + 1e-8) // Endpunkte nicht mit berücksichtigen //if (!((Math.Abs(cutPlace[i]) < 1e-8) || (Math.Abs(cutPlace[i] - 1) < 1e-8))) { realCut = true; break; } } else { //if (cutPlace[i] < 1e-8 || cutPlace[i] > 1 - 1e-8) // Endpunkte mit berücksichtigen { realCut = true; break; } } } if (realCut) { int k = -1; if (lowerEnd) { param = double.MinValue; } else { param = double.MaxValue; } double eps; // wenn distToCurve gesetzt ist, dann bleibt ein exakt getrimmtes am Ende gültig, ansonsten wird die nächste Querkurve verwendet if (distToCurve.Length == 0) { eps = 1e-8; } else { if (sourceCurve != null && sourceCurve.Length > 0) // eine Zielkurve wurde angewählt. Schnitte dürfen jetzt vor dem Ende von iCurve sein //eps = -Math.Abs(distToCurve.Length) / sourceCurve.Length; { eps = -1.0; // egal, Hauptsache auf der Kurve } else { eps = -1e-8; } } for (int i = 0; i < cutPlace.Length; ++i) { if (lowerEnd) { // verlängern nach hinten, der größte Wert, der kleiner Null und ungleich quasi Null if ((cutPlace[i] > param) && (cutPlace[i] < 0.0 - eps)) { param = cutPlace[i]; k = i; } } else { // verlängern nach vorne, der kleinste Wert, der größer 1.0 und ungleich quasi 1.0 if ((cutPlace[i] < param) && (cutPlace[i] > 1.0 + eps)) { param = cutPlace[i]; k = i; } } } if (k >= 0) // was gefunden { newCurve = iCurve.Clone(); if (distToCurve.Length != 0.0) { // zusätzlich länger oder kürzer machen ICurve targetCurve = sourceCurve; if (targetCurves != null) { targetCurve = targetCurves[k]; } Plane pl; if (Curves.GetCommonPlane(iCurve, targetCurve, out pl)) { // muss der Fall sein ICurve2D targetCurve2d = targetCurve.GetProjectedCurve(pl); ICurve2D parl1 = targetCurve2d.Parallel(-distToCurve.Length, true, Precision.eps, 0.0); ICurve2D parl2 = targetCurve2d.Parallel(distToCurve.Length, true, Precision.eps, 0.0); ICurve2D newCurve2d = newCurve.GetProjectedCurve(pl); // im 2d verlängern if (lowerEnd) { newCurve2d.StartPoint = newCurve2d.PointAt(param); } else { newCurve2d.EndPoint = newCurve2d.PointAt(param); } if (lowerEnd) { // jetzt nur den Vorwärtsfall betrachten newCurve2d.Reverse(); } // betrachte beide Parallelen, wir kennen die Richtungen nicht GeoPoint2DWithParameter[] gp1 = newCurve2d.Intersect(parl1); GeoPoint2DWithParameter[] gp2 = newCurve2d.Intersect(parl2); double bestPar; if (distToCurve.Length > 0) { // Kurve muss kürzer werden bestPar = 0.0; for (int i = 0; i < gp1.Length; i++) { if (gp1[i].par2 >= 0 && gp1[i].par2 <= 1 && gp1[i].par1 <1 && gp1[i].par1> bestPar) { bestPar = gp1[i].par1; } } for (int i = 0; i < gp2.Length; i++) { if (gp2[i].par2 >= 0 && gp2[i].par2 <= 1 && gp2[i].par1 <1 && gp2[i].par1> bestPar) { bestPar = gp2[i].par1; } } } else { bestPar = double.MaxValue; for (int i = 0; i < gp1.Length; i++) { if (gp1[i].par2 >= 0 && gp1[i].par2 <= 1 && gp1[i].par1 > 1 && gp1[i].par1 < bestPar) { bestPar = gp1[i].par1; } } for (int i = 0; i < gp2.Length; i++) { if (gp2[i].par2 >= 0 && gp2[i].par2 <= 1 && gp2[i].par1 > 1 && gp2[i].par1 < bestPar) { bestPar = gp2[i].par1; } } } // den gefundenen Punkt auf die Kurve setzen if (bestPar > 0 && bestPar < double.MaxValue) { GeoPoint pp = pl.ToGlobal(newCurve2d.PointAt(bestPar)); param = iCurve.PositionOf(pp); // param ist das eigentliche Ergebnis, welches bei onDone verwendet wird if (lowerEnd) { newCurve.StartPoint = pp; } else { newCurve.EndPoint = pp; } } } } else { if (lowerEnd) { newCurve.StartPoint = iCurve.PointAt(param); } else { newCurve.EndPoint = iCurve.PointAt(param); } } (newCurve as IGeoObject).CopyAttributes(iCurve as IGeoObject); //Color backColor = base.Frame.GetColorSetting("Colors.Feedback", Color.DarkGray); //if (newCurve is IColorDef) // (newCurve as IColorDef).ColorDef = new ColorDef("", backColor); base.ActiveObject = (newCurve as IGeoObject); base.FeedBack.AddSelected(newCurve as IGeoObject);// letzte Linie einfügen return(true); } } } param = 0.0; return(false); }