private bool showLine() { ArrayList usableCurves = new ArrayList(); double mindist = double.MaxValue; if (tangCurves == null) { return(false); } for (int i = 0; i < tangCurves.Length; ++i) { Plane pl; // Element hat eine Ebene: if (tangCurves[i].GetPlanarState() == PlanarState.Planar) { pl = tangCurves[i].GetPlane(); } else { // Element hat keine Ebene: Eine machen, falls möglich! try { pl = new Plane(tangCurves[i].StartPoint, tangCurves[i].EndPoint, circlePoint); } catch (PlaneException) { break; } } if (Precision.IsPointOnPlane(circlePoint, pl)) { ICurve2D l2D1 = tangCurves[i].GetProjectedCurve(pl); GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, pl.Project(circlePoint), circRad); if (tangentPoints.Length > 0) { // eine gültige Lösung ist gefunden usableCurves.Add(tangCurves[i]); // zur lokalen Liste zufügen for (int k = 0; k < tangentPoints.Length; k += 2) { double dist = Geometry.Dist(tangentPoints[k + 1], pl.Project(radiusPoint)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist // (/ 2) und (* 2), da pro Lösung zwei Punkte geliefert werden int l = (k + 2 * (Math.Abs(selSol) % (tangentPoints.Length / 2))) % tangentPoints.Length; center = tangentPoints[l]; } } } if (mindist < double.MaxValue) { circRadCalc = (Math.Abs(l2D1.Distance(pl.Project(radiusPoint))) + Math.Abs(Geometry.Dist(circlePoint, radiusPoint))) / 2.0; // base.MultiSolution = true; base.MultiSolutionCount = tangentPoints.Length / 2; 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 base.ShowActiveObject = true; return(true); } } } base.MultiSolutionCount = 0; // base.MultiSolution = false; base.ShowActiveObject = false; return(false); }
protected override bool FindTangentialPoint(MouseEventArgs e, IView vw, out GeoPoint found) { double mindist = double.MaxValue; found = GeoPoint.Origin; // nur beim dritten Punkt: if (CurrentInput == pointInput && curve1Input.Fixed && curve2Input.Fixed) { GeoObjectList l = base.GetObjectsUnderCursor(e.Location); l.DecomposeAll(); GeoPoint inpoint = base.WorldPoint(e.Location); Plane pln = arc.Plane; bool plnOK = false; for (int i = 0; i < l.Count; i++) { if (l[i] is ICurve) { ICurve curve = l[i] as ICurve; if (curve is Line) { // alles in einer Ebene? In welcher? plnOK = !((pln.Distance((curve as Line).StartPoint) > Precision.eps) || (pln.Distance((curve as Line).EndPoint) > Precision.eps)); } if (curve is Ellipse) { plnOK = (curve.IsInPlane(pln)); // alles in einer Ebene? } if (plnOK) { // Achtung! Die Sortierung mit Linie(n) am Anfang ist wichtig für die Auswertung des Abstandes!! ICurve2D l2D1 = (l[i] as ICurve).GetProjectedCurve(pln); ICurve2D l2D2 = tang1Curves[selected1].GetProjectedCurve(pln); ICurve2D l2D3 = tang2Curves[selected2].GetProjectedCurve(pln); GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, l2D2, l2D3, pln.Project(inpoint), pln.Project(object1Point), pln.Project(object2Point)); if (tangentPoints.Length > 0) { for (int k = 0; k < tangentPoints.Length; k += 4) { double dist = Geometry.Dist(tangentPoints[k + 1], pln.Project(inpoint)); if (dist < mindist) { mindist = dist; found = pln.ToGlobal(tangentPoints[k + 1]); } } } } } } } return(mindist != double.MaxValue); }
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(); double mindist = double.MaxValue; double arcRadLoc; if (tangCurves == null) { return(false); } arcRadLoc = arcRad; for (int i = 0; i < tangCurves.Length; ++i) { Plane pl; if (tangCurves[i].GetPlanarState() == PlanarState.Planar) { pl = tangCurves[i].GetPlane(); } else { try { pl = new Plane(tangCurves[i].StartPoint, tangCurves[i].EndPoint, circlePoint); } catch (PlaneException) { break; } } if (Precision.IsPointOnPlane(circlePoint, pl)) { ICurve2D l2D1 = tangCurves[i].GetProjectedCurve(pl); if (l2D1 is Path2D) { (l2D1 as Path2D).Flatten(); } GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, pl.Project(circlePoint), arcRad); if (tangentPoints.Length > 0) { // eine gültige Linie ist gefunden usableCurves.Add(tangCurves[i]); // zur lokalen Liste zufügen for (int k = 0; k < tangentPoints.Length; k += 2) { double dist = Geometry.Dist(tangentPoints[k + 1], 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 // 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 + 2 * ((Math.Abs(selSol) / 2) % (tangentPoints.Length / 2))) % 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(pl.Project(circlePoint), center); } else { startAngle = new Angle(pl.Project(circlePoint), center); endAngle = new Angle(tangentPoints[l + 1], center); } } } } if (mindist < double.MaxValue) { arcRadCalc = (Math.Abs(l2D1.Distance(pl.Project(radiusPoint))) + Math.Abs(Geometry.Dist(circlePoint, radiusPoint))) / 2.0; // base.MultiSolution = true; base.MultiSolutionCount = tangentPoints.Length; // /2 *2 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 base.ShowActiveObject = true; return(true); } } } base.MultiSolutionCount = 0; // base.MultiSolution = false; base.ShowActiveObject = false; return(false); }
private bool showLineDiam() { ArrayList usable1Curves = new ArrayList(); Plane pl; double mindist = double.MaxValue; if (tangCurves == null) { return(false); } for (int i = 0; i < tangCurves.Length; ++i) { if (tangCurves[i].GetPlanarState() == PlanarState.Planar) { pl = tangCurves[i].GetPlane(); } else { // Element hat keine Ebene: Eine machen, falls möglich! try { pl = new Plane(tangCurves[i].StartPoint, tangCurves[i].EndPoint, circlePoint); } catch (PlaneException) { break; } } if (Precision.IsPointOnPlane(radiusPoint, pl)) { ICurve2D l2D1 = tangCurves[i].GetProjectedCurve(pl); ICurve2D l2D2 = new Circle2D(pl.Project(circlePoint), 0.0); ICurve2D l2D3 = new Circle2D(pl.Project(radiusPoint), 0.0); GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, l2D2, l2D3, pl.Project(objectPoint), pl.Project(circlePoint), pl.Project(radiusPoint)); if (tangentPoints.Length > 0) { // eine gültige Linie ist gefunden usable1Curves.Add(tangCurves[i]); // zur lokalen Liste zufügen for (int l = 0; l < tangentPoints.Length; l += 4) { double dist = Geometry.Dist(tangentPoints[l + 1], pl.Project(objectPoint)) + Geometry.Dist(tangentPoints[l + 2], pl.Project(circlePoint)) + Geometry.Dist(tangentPoints[l + 3], pl.Project(radiusPoint)); if (dist < mindist) { mindist = dist; selected = usable1Curves.Count - 1; // merken, welche Kurven die aktuell benutzten sind // 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]; arcRadCalc = Geometry.Dist(tangentPoints[m + 1], center) * 2.0; } } if (mindist < double.MaxValue) { // base.MultiSolution = true; base.MultiSolutionCount = tangentPoints.Length / 4; arc.SetCirclePlaneCenterRadius(pl, pl.ToGlobal(center), arcRad); tangCurves = (ICurve[])usable1Curves.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 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); }
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); }
protected override bool FindTangentialPoint(MouseEventArgs e, IView vw, out GeoPoint found) { double mindist = double.MaxValue; found = GeoPoint.Origin; // nur beim dritten Punkt: if (CurrentInput == arcPoint3Input && arcPoint1Input.Fixed && arcPoint2Input.Fixed) { GeoObjectList l = base.GetObjectsUnderCursor(e.Location); l.DecomposeAll(); GeoPoint inpoint = base.WorldPoint(e.Location); Plane pln = Plane.XYPlane; bool plnOK = false; for (int i = 0; i < l.Count; i++) { if (l[i] is ICurve) { ICurve curve = l[i] as ICurve; if (curve is Line) { double eps; bool linear; // alles in einer Ebene? In welcher? pln = Plane.FromPoints(new GeoPoint[] { circlePoint1, circlePoint2, (curve as Line).StartPoint, (curve as Line).EndPoint }, out eps, out linear); plnOK = !(linear || eps > Precision.eps); } if (curve is Ellipse) { pln = (curve as Ellipse).GetPlane(); // alles in einer Ebene? plnOK = !((pln.Distance(circlePoint1) > Precision.eps) || (pln.Distance(circlePoint2) > Precision.eps)); } if (plnOK) { // Hilfskreise machen um die ersten 2 Punkte: Ellipse circLoc1; circLoc1 = Ellipse.Construct(); circLoc1.SetCirclePlaneCenterRadius(pln, circlePoint1, 0.0); Ellipse circLoc2; circLoc2 = Ellipse.Construct(); circLoc2.SetCirclePlaneCenterRadius(pln, circlePoint2, 0.0); // Achtung! Die Sortierung mit Linie(n) am Anfang ist wichtig für die Auswertung des Abstandes!! ICurve2D l2D1 = (l[i] as ICurve).GetProjectedCurve(pln); ICurve2D l2D2 = circLoc1.GetProjectedCurve(pln); ICurve2D l2D3 = circLoc2.GetProjectedCurve(pln); GeoPoint2D[] tangentPoints = Curves2D.TangentCircle(l2D1, l2D2, l2D3, pln.Project(inpoint), pln.Project(circlePoint1), pln.Project(circlePoint2)); if (tangentPoints.Length > 0) { for (int k = 0; k < tangentPoints.Length; k += 4) { double dist = Geometry.Dist(tangentPoints[k + 1], pln.Project(inpoint)); if (dist < mindist) { mindist = dist; found = pln.ToGlobal(tangentPoints[k + 1]); } } } } } } } return(mindist != double.MaxValue); }
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 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 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); }
/// <summary> /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.MinDistance (ICurve2D)"/> /// </summary> /// <param name="Other"></param> /// <returns></returns> public override double MinDistance(ICurve2D Other) { if (Other is Line2D) { return(Other.MinDistance(this)); // bei der Linie ist es definiert } else if (Other is Circle2D) { double minDist = Curves2D.SimpleMinimumDistance(this, Other); // dort werden die Schnitt- Start- Endpunkte miteinander verrechnet // jetzt nur noch gucken, ob sich die beiden Kreise oder Bögen annähern Circle2D c = Other as Circle2D; double cdist = Geometry.Dist(c.center, center); if (cdist < Precision.eps) { return(minDist); // mit gleichen Mittelpunkten funktioniert } // das folgende nicht, aber der Abstand ist schon von SimpleMinimumDistance bestimmt // da dort auch die Fußpunkte verwendung finden if (cdist > c.radius + radius) { // Annäherung zweier nicht schneidenden Kreise GeoVector2D dir = c.center - center; // von hier zum anderen dir.Norm(); GeoPoint2D p1 = center + radius * dir; GeoPoint2D p2 = c.center + c.radius * dir.Opposite(); double pos1 = this.PositionOf(p1); double pos2 = c.PositionOf(p2); if (pos1 >= 0.0 && pos1 <= 1.0 && pos2 >= 0.0 && pos2 <= 1.0) { minDist = Math.Min(minDist, cdist - c.radius - radius); } } else if (radius - c.radius > cdist) { // Kreis c liegt innerhalb von diesem Kreis GeoVector2D dir = c.center - center; // von hier zum anderen dir.Norm(); GeoPoint2D p1 = center + radius * dir; GeoPoint2D p2 = c.center + c.radius * dir; double pos1 = this.PositionOf(p1); double pos2 = c.PositionOf(p2); if (pos1 >= 0.0 && pos1 <= 1.0 && pos2 >= 0.0 && pos2 <= 1.0) { minDist = Math.Min(minDist, Geometry.Dist(p1, p2)); } } else if (c.radius - radius > cdist) { // dieser Kreis liegt innerhalb von c GeoVector2D dir = center - c.center; dir.Norm(); GeoPoint2D p1 = c.center + c.radius * dir; GeoPoint2D p2 = center + radius * dir; double pos1 = c.PositionOf(p1); double pos2 = PositionOf(p2); if (pos1 >= 0.0 && pos1 <= 1.0 && pos2 >= 0.0 && pos2 <= 1.0) { minDist = Math.Min(minDist, Geometry.Dist(p1, p2)); } } return(minDist); } else { return(base.MinDistance(Other)); } }
/// <summary> /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.MinDistance (ICurve2D)"/> /// </summary> /// <param name="Other"></param> /// <returns></returns> public override double MinDistance(ICurve2D Other) { if (Other is Line2D) { Line2D l = Other as Line2D; // schneller Vorabtest auf Schnitt: (noch nicht getestet) double f1 = (startPoint.x - endPoint.x) * (l.endPoint.y - endPoint.y) - (startPoint.y - endPoint.y) * (l.endPoint.x - endPoint.x); double f2 = (startPoint.x - endPoint.x) * (l.startPoint.y - endPoint.y) - (startPoint.y - endPoint.y) * (l.startPoint.x - endPoint.x); if (f1 * f2 < 0.0) { // verschiedenes Vorzeichen double f3 = (l.startPoint.x - l.endPoint.x) * (endPoint.y - l.endPoint.y) - (l.startPoint.y - l.endPoint.y) * (endPoint.x - l.endPoint.x); double f4 = (l.startPoint.x - l.endPoint.x) * (startPoint.y - l.endPoint.y) - (l.startPoint.y - l.endPoint.y) * (startPoint.x - l.endPoint.x); if (f3 * f4 < 0.0) { return(0.0); // echter Schnittpunkt } } double minDist = double.MaxValue; double dx1 = endPoint.x - startPoint.x; double dy1 = endPoint.y - startPoint.y; bool DoDx1 = Math.Abs(dx1) > Math.Abs(dy1); double dx2 = l.endPoint.x - l.startPoint.x; double dy2 = l.endPoint.y - l.startPoint.y; bool DoDx2 = Math.Abs(dx2) > Math.Abs(dy2); double d; // Berechnung der Fußpunktabstände, wenn sie auf die andere Linie treffen GeoPoint2D p = Geometry.DropPL(l.startPoint, startPoint, endPoint); if (DoDx1) { d = (p.x - startPoint.x) / dx1; } else { d = (p.y - startPoint.y) / dy1; } if (d >= 0.0 && d <= 1.0) { minDist = Math.Min(minDist, Geometry.Dist(p, l.startPoint)); } p = Geometry.DropPL(l.endPoint, startPoint, endPoint); if (DoDx1) { d = (p.x - startPoint.x) / dx1; } else { d = (p.y - startPoint.y) / dy1; } if (d >= 0.0 && d <= 1.0) { minDist = Math.Min(minDist, Geometry.Dist(p, l.endPoint)); } p = Geometry.DropPL(startPoint, l.startPoint, l.endPoint); if (DoDx2) { d = (p.x - l.startPoint.x) / dx2; } else { d = (p.y - l.startPoint.y) / dy2; } if (d >= 0.0 && d <= 1.0) { minDist = Math.Min(minDist, Geometry.Dist(p, startPoint)); } p = Geometry.DropPL(endPoint, l.startPoint, l.endPoint); if (DoDx2) { d = (p.x - l.startPoint.x) / dx2; } else { d = (p.y - l.startPoint.y) / dy2; } if (d >= 0.0 && d <= 1.0) { minDist = Math.Min(minDist, Geometry.Dist(p, endPoint)); } if (minDist == double.MaxValue) { // kein Fußpunkt auf der anderen Linie: die gegenseitigen Start/Endpunkt // Abstände verwenden minDist = Math.Min(minDist, Geometry.Dist(l.startPoint, endPoint)); minDist = Math.Min(minDist, Geometry.Dist(l.endPoint, endPoint)); minDist = Math.Min(minDist, Geometry.Dist(l.startPoint, startPoint)); minDist = Math.Min(minDist, Geometry.Dist(l.endPoint, startPoint)); } return(minDist); } else if (Other is Arc2D) { double minDist = Curves2D.SimpleMinimumDistance(this, Other); Arc2D a = Other as Arc2D; GeoPoint2D[] fp = PerpendicularFoot(a.Center); for (int i = 0; i < fp.Length; ++i) { GeoPoint2D p = fp[i]; double pos = PositionOf(p); if (pos >= 0.0 && pos <= 1.0) { pos = a.PositionOf(p); if (pos >= 0.0 && pos <= 1.0) { double d = Geometry.Dist(p, a.Center); if (d > a.Radius) { minDist = Math.Min(minDist, d - a.Radius); } } } } return(minDist); } else if (Other is Circle2D) { double minDist = Curves2D.SimpleMinimumDistance(this, Other); Circle2D c = Other as Circle2D; GeoPoint2D[] fp = PerpendicularFoot(c.Center); for (int i = 0; i < fp.Length; ++i) { GeoPoint2D p = fp[i]; double pos = PositionOf(p); if (pos >= 0.0 && pos <= 1.0) { double d = Geometry.Dist(p, c.Center); if (d > c.Radius) { minDist = Math.Min(minDist, d - c.Radius); } } } return(minDist); } else { return(base.MinDistance(Other)); } }
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 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); }