public override bool TryPointDeriv2At(double position, out GeoPoint2D point, out GeoVector2D deriv, out GeoVector2D deriv2) { // not yet tested point = fromUnit * new GeoPoint2D(position, Math.Sin(ustart + position * udiff)); deriv = fromUnit * new GeoVector2D(1, udiff * Math.Cos(ustart + position * udiff)); deriv2 = fromUnit * new GeoVector2D(1, -udiff * udiff * Math.Sin(ustart + position * udiff)); return(true); }
private Plane zPosition; // die Raum-Ebene, in deren Mittelpunkt der Kreis bezüglich seine 2d Darstellung liegt internal void RecalcUnitCircle() { // berechnen der beiden ModOps fromUnitCircle und toUnitCircle // Achtung: das berücksichtigt nicht ein Linkssystem. Das ist somit eigentlich falsch // im Linkssystem müsste das Vorzeichen von MinorRadius negativ sein, damit die Matrix stimmt! double MajorRadius = majorAxis.Length; double MinorRadius = minorAxis.Length; if (GeoVector2D.Orientation(majorAxis, minorAxis) < 0) { // eingeführt wg. dem Umdrehen eines Faces mit elliptischen Begrenzungen (11.3.15), Datei 97871_086103_032.cdb, nach Shell.AssertOutwardOrientation stimmt das Face Nr. 8 nicht mehr MinorRadius = -MinorRadius; } if (MajorRadius == 0.0 || MinorRadius == 0.0) { fromUnitCircle = toUnitCircle = ModOp2D.Identity; } else { Angle MajorAngle = majorAxis.Angle; double s = Math.Sin(MajorAngle); double c = Math.Cos(MajorAngle); toUnitCircle = new ModOp2D(c / MajorRadius, s / MajorRadius, (-c * center.x - s * center.y) / MajorRadius, -s / MinorRadius, c / MinorRadius, (s * center.x - c * center.y) / MinorRadius); fromUnitCircle = new ModOp2D(MajorRadius * c, -MinorRadius * s, center.x, MajorRadius * s, MinorRadius * c, center.y); } }
static public void SpaceDown(GeoObjectList gl, Projection projection, Project pr) { using (pr.Undo.UndoFrame) { IGeoObject[] geoArray = new IGeoObject[gl.Count]; for (int i = 0; i < gl.Count; ++i) // umkopieren auf ein Array, um den Sort machen zu können { geoArray[i] = gl[i]; } // hier nun Sort, der Compare steht oben als lokal class und braucht die Parameter: Sort nach y = false und pm Array.Sort(geoArray, 0, geoArray.Length, new CompareGeoObject(false, projection)); // die Rechtecke des ersten und letzten Objeks für die Gesamtausdehnung BoundingRect reStart = IGeoObjectImpl.GetExtent(geoArray[0], projection, false); BoundingRect reEnd = IGeoObjectImpl.GetExtent(geoArray[geoArray.Length - 1], projection, false); double reTotal = reEnd.Top - reStart.Bottom; // Gesamtausdehnung double distRe = 0; for (int i = 0; i < geoArray.Length; ++i) // Summe der Ausdehnung der Einzelnen: { BoundingRect re = IGeoObjectImpl.GetExtent(geoArray[i], projection, false); distRe = distRe + re.Height; } double space = (reTotal - distRe) / (geoArray.Length - 1); // Gesamt - Summe Einzelne / Zwischenräume double pos = reStart.Top; for (int i = 1; i < geoArray.Length - 1; ++i) // vom zweiten bis zum vorletzten, die Äußeren bleiben unverändert { BoundingRect re = IGeoObjectImpl.GetExtent(geoArray[i], projection, false); GeoVector2D trans2D = new GeoVector2D(0, pos + space - re.Bottom); pos = pos + space + re.Height; // pos hochzählen auf den oberen Rand des aktuellen GeoVector trans = projection.DrawingPlane.ToGlobal(trans2D); ModOp m = ModOp.Translate(trans); geoArray[i].Modify(m); } } }
private static void RefineIntersectionPoint(Ellipse2D e1, Ellipse2D e2, ref GeoPoint2DWithParameter ip) { // hier mir Param arbeiten, da es sich auch um einen Ellipsenbogen handeln kann double par1 = e1.ParamOf(ip.p); double par2 = e2.ParamOf(ip.p); GeoPoint2D p1 = e1.PointAtParam(par1); GeoPoint2D p2 = e2.PointAtParam(par2); int counter = 0; while (!Precision.IsEqual(p1, p2)) { GeoVector2D d1 = e1.DirectionAtParam(par1); GeoVector2D d2 = e2.DirectionAtParam(par2); GeoPoint2D p; if (Geometry.IntersectLL(p1, d1, p2, d2, out p)) { par1 = e1.ParamOf(p); par2 = e2.ParamOf(p); p1 = e1.PointAtParam(par1); p2 = e2.PointAtParam(par2); ip.p = p; } else { break; } ++counter; if (counter > 100) { break; } } ip.par1 = e1.PositionOf(ip.p); // richtige Werte auch für Arc ip.par2 = e2.PositionOf(ip.p); }
public static bool SameNotOppositeDirection(GeoVector2D v1, GeoVector2D v2, bool VectorsAreNormalized) { Angle a1 = new Angle(v1); Angle a2 = new Angle(v2); return(IsEqual(a1, a2)); }
public override bool TryPointDeriv3At(double position, out GeoPoint2D point, out GeoVector2D deriv1, out GeoVector2D deriv2, out GeoVector2D deriv3) { double sweepParameter; if (counterClock) { sweepParameter = 2.0 * Math.PI; } else { sweepParameter = -2.0 * Math.PI; } double u = position * sweepParameter; double su = Math.Sin(u); double cu = Math.Cos(u); point = fromUnitCircle * new GeoPoint2D(cu, su); double pp = 2 * Math.PI; double ppp = 4 * Math.PI * Math.PI; double pppp = 8 * Math.PI * Math.PI * Math.PI; if (!counterClock) { pp = -pp; pppp = -pppp; } deriv1 = pp * new GeoVector2D(fromUnitCircle[0, 1] * cu - fromUnitCircle[0, 0] * su, fromUnitCircle[1, 1] * cu - fromUnitCircle[1, 0] * su); deriv2 = ppp * new GeoVector2D(-fromUnitCircle[0, 1] * su - fromUnitCircle[0, 0] * cu, -fromUnitCircle[1, 1] * su - fromUnitCircle[1, 0] * cu); deriv3 = pppp * new GeoVector2D(fromUnitCircle[0, 0] * su - fromUnitCircle[0, 1] * cu, fromUnitCircle[1, 0] * su - fromUnitCircle[1, 1] * cu); return(true); }
public static EllipseArc2D Create(GeoPoint2D center, GeoVector2D majorAxis, GeoVector2D minorAxis, GeoPoint2D startPoint, GeoPoint2D endPoint, bool counterClock) { // bestimme die beiden Winkel GeoVector2D majAx; GeoVector2D minAx; GeoPoint2D left, right, bottom, top; Geometry.PrincipalAxis(center, majorAxis, minorAxis, out majAx, out minAx, out left, out right, out bottom, out top, false); ModOp2D toUnit = ModOp2D.Fit(new GeoPoint2D[] { center, center + majAx, center + minAx }, new GeoPoint2D[] { GeoPoint2D.Origin, GeoPoint2D.Origin + GeoVector2D.XAxis, GeoPoint2D.Origin + GeoVector2D.YAxis }, true); GeoPoint2D p = toUnit * startPoint; double sa = p.ToVector().Angle.Radian; p = toUnit * endPoint; double ea = p.ToVector().Angle.Radian; double sw; if (counterClock) { sw = ea - sa; if (sw <= 0.0) { sw += Math.PI * 2.0; // geändert auf <= bzw. >=, da sonst aus Vollkreisen Leerkreise werden } } else { sw = ea - sa; if (sw >= 0.0) { sw -= Math.PI * 2.0; } } return(new EllipseArc2D(center, majAx, minAx, sa, sw, left, right, bottom, top)); }
public override bool TryPointDeriv2At(double position, out GeoPoint2D point, out GeoVector2D deriv, out GeoVector2D deriv2) { point = PointAt(position); deriv = endPoint - startPoint; deriv2 = GeoVector2D.NullVector; return(true); }
void SetSizeGeoPoint(GeneralGeoPointAction sender, GeoPoint NewValue) { if (polyline.IsRectangle) { double w = Geometry.DistPL(NewValue, polyline.RectangleLocation, polyline.ParallelogramSecondaryDirection); double h = Geometry.DistPL(NewValue, polyline.RectangleLocation, polyline.ParallelogramMainDirection); if (Math.Abs(w) > Precision.eps && Math.Abs(h) > Precision.eps) { polyline.RectangleWidth = w; polyline.RectangleHeight = h; } } else if (polyline.IsParallelogram) { Plane pln = polyline.GetPlane(); GeoPoint2D fix = pln.Project(polyline.ParallelogramLocation); GeoVector2D dirx = pln.Project(polyline.ParallelogramMainDirection); GeoVector2D diry = pln.Project(polyline.ParallelogramSecondaryDirection); GeoPoint2D np = pln.Project(NewValue); GeoPoint2D xp, yp; if (Geometry.IntersectLL(fix, dirx, np, diry, out xp) && Geometry.IntersectLL(fix, diry, np, dirx, out yp)) { polyline.ParallelogramWidth = fix | xp; polyline.ParallelogramHeight = fix | yp; } } }
/// <summary> /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.Distance (GeoPoint2D)"/> /// </summary> /// <param name="p"></param> /// <returns></returns> public override double Distance(GeoPoint2D p) { double mindist = double.MaxValue; for (int i = 1; i < vertex.Length; ++i) { GeoPoint2D sp = vertex[i - 1]; GeoPoint2D ep = vertex[i]; GeoVector2D dir = ep - sp; GeoPoint2D dr = Geometry.DropPL(p, sp, ep); double pos = Geometry.LinePar(sp, dir, p); double d; if (pos >= 0.0 && pos <= 1.0) { d = Geometry.DistPL(p, sp, dir); } else { d = Math.Min(Geometry.Dist(p, sp), Geometry.Dist(p, ep)); } if (Math.Abs(d) < Math.Abs(mindist)) { mindist = d; } // das ist der seitenrichtige Abstand (Vorzeichen), außer bei Eckpunkten // da muss evtl. noch nachgebessert werden } return(mindist); }
/// <summary> /// Moves the rectangle by the provided offset /// </summary> /// <param name="offset">Offset to move</param> public void Move(GeoVector2D offset) { Left += offset.x; Right += offset.x; Bottom += offset.y; Top += offset.y; }
internal void Add(IEnumerable <Edge> edges, Face onThisFace, double arrowsize, System.Drawing.Color clr, int debugHint) { Random rnd = new Random(); foreach (Edge edg in edges) { if (edg.Curve2D(onThisFace) == null) { continue; } int dbgh = debugHint; if (debugHint == -1) { dbgh = edg.GetHashCode(); } Add(edg.Curve2D(onThisFace), clr, dbgh); // noch einen Richtungspfeil zufügen GeoPoint2D[] arrowpnts = new GeoPoint2D[3]; double pos = 0.3 + rnd.NextDouble() * 0.4; // to have different positions when the same curve is displayed twice GeoVector2D dir = edg.Curve2D(onThisFace).DirectionAt(pos).Normalized; arrowpnts[1] = edg.Curve2D(onThisFace).PointAt(pos); arrowpnts[0] = arrowpnts[1] - arrowsize * dir + arrowsize * dir.ToLeft(); arrowpnts[2] = arrowpnts[1] - arrowsize * dir + arrowsize * dir.ToRight(); Polyline2D pl2d = new Polyline2D(arrowpnts); Add(pl2d, clr, edg.GetHashCode()); } }
private void RotateWithPlanes() { // get rotation axis from the two planes if (src.Intersect(trg, out GeoPoint loc, out GeoVector dir)) { // set to original position for (int i = 0; i < block.Count; ++i) { block.Child(i).CopyGeometry(originals[i]); } Plane perp = new Plane(loc, dir); // plane perpendicular to rotation axis GeoVector2D from = perp.Project(dir ^ src.Normal); GeoVector2D to = perp.Project(dir ^ trg.Normal); SweepAngle sw = new SweepAngle(from, to); rotationAngle = sw; rotAngleInput.ForceValue(rotationAngle); ModOp m0 = ModOp.Rotate(loc, dir, sw); ModOp m1 = ModOp.Rotate(loc, -dir, sw); GeoVector n0 = m0 * src.Normal; GeoVector n1 = m1 * src.Normal; ModOp m; // not sure, which rotation is better if (Math.Abs(n0 * trg.Normal) > Math.Abs(n1 * trg.Normal)) { m = ModOp.Rotate(loc, dir, sw + GetOffset()); axisVector = dir; } else { m = ModOp.Rotate(loc, -dir, sw + GetOffset()); axisVector = -dir; } block.Modify(m); base.BasePoint = loc; } }
/// <summary> /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.TangentPointsToAngle (GeoVector2D)"/> /// </summary> /// <param name="direction"></param> /// <returns></returns> public override double[] TangentPointsToAngle(GeoVector2D direction) { double[] res = new double[2]; res[0] = direction.ToRight().Angle.Radian / (Math.PI * 2); res[1] = direction.ToLeft().Angle.Radian / (Math.PI * 2); return(res); }
public override GeoVector DirectionAt(double pos) { GeoPoint2D p = curve2D.PointAt(pos); GeoVector2D dir = curve2D.DirectionAt(pos); surface.DerivationAt(p, out GeoPoint location, out GeoVector diru, out GeoVector dirv); return(dir.x * diru + dir.y * dirv); }
GeoVector2D ICurveTransformation2D.TransformDeriv1(ICurve2D curve, double par) { // gesucht: Richtung im nicht periodischen System GeoPoint2D uv = curve.PointAt(par); GeoVector2D dir = curve.DirectionAt(par); return(new GeoVector2D(Math.Cos(uv.x) * (dir.y) - Math.Sin(uv.x) * (dir.x) * (uv.y - vmin), Math.Cos(uv.x) * (dir.x) * (uv.y - vmin) + Math.Sin(uv.x) * (dir.y))); }
private Angle OnGetLongitude() { // Winkel in der X/Y Ebene GeoVector v = GetGeoVector(); // hier erstmal nur global: GeoVector2D v2d = Frame.ActiveView.Projection.DrawingPlane.Project(v); return(new Angle(v2d)); }
public override GeoPoint2D PositionOf(GeoPoint p) { double r = xAxis.Length; GeoVector v = Geometry.ReBase(p - (location - zAxis), xAxis, yAxis, zAxis); GeoVector2D v2d = new GeoVector2D(v.x, v.y); v2d.Length = r / v.z; return(new GeoPoint2D(v2d.x, v2d.y)); }
/// <summary> /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.Move (double, double)"/> /// </summary> /// <param name="dx"></param> /// <param name="dy"></param> public override void Move(double dx, double dy) { GeoVector2D offset = new GeoVector2D(dx, dy); for (int i = 0; i < vertex.Length; ++i) { vertex[i] = vertex[i] + offset; } }
public EllipseArc2D(GeoPoint2D center, GeoVector2D majorAxis, GeoVector2D minorAxis, double startPar, double sweepPar, GeoPoint2D left, GeoPoint2D right, GeoPoint2D bottom, GeoPoint2D top) : base(center, majorAxis, minorAxis, sweepPar > 0.0, left, right, bottom, top) { this.startPar = startPar; this.sweepPar = sweepPar; startPoint = center + Math.Cos(startPar) * majorAxis + Math.Sin(startPar) * minorAxis; endPoint = center + Math.Cos(startPar + sweepPar) * majorAxis + Math.Sin(startPar + sweepPar) * minorAxis; RecalcQuadrant(); }
protected override void GetTriangulationBasis(out GeoPoint2D[] points, out GeoVector2D[] directions, out double[] positions) { List <double> uvalues = new List <double>(); uvalues.Add(ustart); if (udiff < 0) { double u = 0.0; while (u < ustart) { u += Math.PI / 2; } while (u > ustart) { u -= Math.PI / 2; } while (u > ustart + udiff + 1e-4) { if (u < uvalues[uvalues.Count - 1] - 1e-4) { uvalues.Add(u); } u -= Math.PI / 2; } } else { double u = 0.0; while (u > ustart) { u -= Math.PI / 2; } while (u < ustart) { u += Math.PI / 2; } while (u < ustart + udiff - 1e-4) { if (u > uvalues[uvalues.Count - 1] + 1e-4) { uvalues.Add(u); } u += Math.PI / 2; } } uvalues.Add(ustart + udiff); positions = new double[uvalues.Count]; points = new GeoPoint2D[uvalues.Count]; directions = new GeoVector2D[uvalues.Count]; for (int i = 0; i < uvalues.Count; i++) { positions[i] = ParToPos(uvalues[i]); points[i] = PointAt(positions[i]); directions[i] = DirectionAt(positions[i]); } }
public void MakePositivOriented() { // stellt sicher, dass die majorAxis und minorAxis ein rechtssystem bilden if (GeoVector2D.Orientation(majorAxis, minorAxis) < 0) { minorAxis = -minorAxis; startPar = 2.0 * Math.PI - startPar; sweepPar = -sweepPar; RecalcQuadrant(); } }
public override GeoVector2D DirectionAt(double pos) { double u = PosToPar(pos); double du = Math.Cos(u); GeoVector2D dir = new GeoVector2D(1, du); // enter Integrate[sqrt(1+cos(x)^2),x] at https://www.wolframalpha.com/input/?i=Integrate%5Bsqrt(1%2Bcos(x)%5E2),x%5D // and the result for the full period is 7.64039557805542, but does this help for the length of the direction??? return(fromUnit * (udiff * dir)); }
private EntityObject ExportEllipse(GeoObject.Ellipse elli) { netDxf.Entities.EntityObject entity = null; if (elli.IsArc) { Plane dxfPlane; if (elli.CounterClockWise) { dxfPlane = Import.Plane(Vector3(elli.Center), Vector3(elli.Plane.Normal)); } else { dxfPlane = Import.Plane(Vector3(elli.Center), Vector3(-elli.Plane.Normal)); } if (elli.IsCircle) { GeoObject.Ellipse aligned = GeoObject.Ellipse.Construct(); aligned.SetArcPlaneCenterStartEndPoint(dxfPlane, dxfPlane.Project(elli.Center), dxfPlane.Project(elli.StartPoint), dxfPlane.Project(elli.EndPoint), dxfPlane, true); entity = new netDxf.Entities.Arc(Vector3(aligned.Center), aligned.Radius, aligned.StartParameter / Math.PI * 180, (aligned.StartParameter + aligned.SweepParameter) / Math.PI * 180); entity.Normal = Vector3(dxfPlane.Normal); } else { netDxf.Entities.Ellipse expelli = new netDxf.Entities.Ellipse(Vector3(elli.Center), 2 * elli.MajorRadius, 2 * elli.MinorRadius); entity = expelli; entity.Normal = Vector3(elli.Plane.Normal); Plane cdbplane = elli.Plane; GeoVector2D dir = dxfPlane.Project(cdbplane.DirectionX); SweepAngle rot = new SweepAngle(GeoVector2D.XAxis, dir); expelli.Rotation = rot.Degree; SetEllipseParameters(expelli, elli.StartParameter, elli.StartParameter + elli.SweepParameter); } } else { if (elli.IsCircle) { entity = new netDxf.Entities.Circle(Vector3(elli.Center), elli.Radius); entity.Normal = Vector3(elli.Plane.Normal); } else { netDxf.Entities.Ellipse expelli = new netDxf.Entities.Ellipse(Vector3(elli.Center), 2 * elli.MajorRadius, 2 * elli.MinorRadius); entity = expelli; entity.Normal = Vector3(elli.Plane.Normal); Plane dxfplane = Import.Plane(expelli.Center, expelli.Normal); // this plane is not correct, it has to be rotated Plane cdbplane = elli.Plane; GeoVector2D dir = dxfplane.Project(cdbplane.DirectionX); SweepAngle rot = new SweepAngle(GeoVector2D.XAxis, dir); expelli.Rotation = rot.Degree; } } return(entity); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.VDirection (GeoPoint2D)"/> /// </summary> /// <param name="uv"></param> /// <returns></returns> public override GeoVector VDirection(GeoPoint2D uv) { double pos = GetPos(uv.y); GeoVector2D dir = basisCurve2D.DirectionAt(pos); //dir = (1.0 / (curveEndParameter - curveStartParameter)) * dir; // dir ist die Änderung um 1 also volle Kurvenlänge // 15.8.17: die Skalierung von dir ist wohl falsch: NewtonLineintersection läuft mit obiger Zeile nicht richtig, so aber perfekt // pitch fehlt noch, ist vermutlich nicht nötig ModOp rot = ModOp.Rotate(1, (SweepAngle)uv.x); return(toSurface * rot * dir); }
static public void AlignPageCenter(GeoObjectList gl, double width, double height, Project pr) { using (pr.Undo.UndoFrame) { // nur in der Draufsicht, sonst macht das keinen Sinn BoundingRect re = gl.GetExtent(Projection.FromTop, false, false); GeoVector2D trans2D = new GeoVector2D(width / 2.0 - (re.Bottom + re.Top) / 2, height / 2.0 - (re.Bottom + re.Top) / 2); GeoVector trans = Plane.XYPlane.ToGlobal(trans2D); ModOp m = ModOp.Translate(trans); gl.Modify(m); } }
static public Arc2D From2PointsAndTangents(GeoPoint2D sp, GeoVector2D sd, GeoPoint2D ep, GeoVector2D ed) { if (Geometry.IntersectLL(sp, sd.ToLeft(), ep, ed.ToLeft(), out GeoPoint2D mp)) { bool cc = Geometry.OnLeftSide(mp, sp, ep); return(new Arc2D(mp, sp | mp, sp, ep, cc)); } else { return(null); } }
/// <summary> /// Constructs the angle that is needed to rotate the first vector counterclockwise to reach the second vector (between 0 and 2.0*Math.PI) /// </summary> /// <param name="v1">First vector</param> /// <param name="v2">Second vector</param> public Angle(GeoVector2D v1, GeoVector2D v2) { a = Math.Acos((v1.x * v2.x + v1.y * v2.y) / ((Math.Sqrt(v1.x * v1.x + v1.y * v1.y)) * Math.Sqrt(v2.x * v2.x + v2.y * v2.y))); if (a < 0.0) { a += 2.0 * Math.PI; } if (a >= 2.0 * Math.PI) { a -= 2.0 * Math.PI; } }
/// <summary> /// Constructs the angle of the given vector. X-axis is 0, counterclockwise. /// </summary> /// <param name="v">vector to define the angle</param> public Angle(GeoVector2D v) { a = Math.Atan2(v.y, v.x); if (a < 0.0) { a += 2.0 * Math.PI; } if (a >= 2.0 * Math.PI) { a -= 2.0 * Math.PI; } }
public static bool IsPerpendicular(GeoVector2D v1, GeoVector2D v2, bool VectorsAreNormalized) { if (v1.Length < eps) { return(true); // oder was? } if (v2.Length < eps) { return(true); // oder was? } return(Math.Abs(v1 * v2) / (v1.Length * v2.Length) < epsa); }