private double OnGetVerPos(DoubleProperty sender) { BoundingRect ext = Model.GetExtent(Projection); if (ext.IsEmpty()) { ext.MinMax(new GeoPoint2D(0.0, 0.0)); } double factor, dx, dy; Projection.GetPlacement(out factor, out dx, out dy); return(ext.Bottom * factor + dy); }
private void OnSetVerPos(DoubleProperty sender, double l) { BoundingRect ext = Model.GetExtent(Projection); if (ext.IsEmpty()) { ext.MinMax(new GeoPoint2D(0.0, 0.0)); } double factor, dx, dy; Projection.GetPlacement(out factor, out dx, out dy); Projection.SetPlacement(factor, dx, l - ext.Bottom * factor); layoutView.Repaint(); }
protected override void GetTriangulationBasis(out GeoPoint2D[] points, out GeoVector2D[] directions, out double[] parameters) { double[] pars = curve3D.GetSavePositions(); List <double> positions = new List <double>(); for (int i = 0; i < pars.Length; i++) { double d = Get2dParameter(pars[i]); if (d > 1e-6 && d < 1.0 - 1e-6) { positions.Add(d); // nur innerhalb des Bereichs und 0 und 1 nicht doppelt } } positions.Add(0.0); positions.Add(1.0); if (positions.Count < 3) { positions.Add(0.5); } positions.Sort(); List <double> lparameters = new List <double>(); for (int i = 0; i < positions.Count; i++) { lparameters.Add(positions[i]); } List <GeoPoint2D> lpoints = new List <GeoPoint2D>(); List <GeoVector2D> ldirections = new List <GeoVector2D>(); for (int i = 0; i < positions.Count; i++) { GeoPoint2D p; GeoVector2D v; PointDirAt(positions[i], out p, out v); lpoints.Add(p); ldirections.Add(v); } bool check = true; // the interpolation should be smooth. Max. bending between interpolation points 45°, which makes sure, the baseApproximation // uses arcs, so that the start- and end-direction are correct while (check && lpoints.Count < 100) { check = false; for (int i = lpoints.Count - 1; i > 0; --i) { if (Math.Abs(new SweepAngle(ldirections[i], ldirections[i - 1])) > Math.PI / 4) { double par = (positions[i] + positions[i - 1]) / 2.0; GeoPoint2D p = PointAt(par); GeoVector2D dir = DirectionAt(par); lpoints.Insert(i, p); ldirections.Insert(i, dir); positions.Insert(i, par); check = true; } } } points = lpoints.ToArray(); directions = ldirections.ToArray(); parameters = positions.ToArray(); if (surface.IsUPeriodic) { for (int i = 1; i < points.Length; i++) { if ((points[i].x - points[i - 1].x) > surface.UPeriod / 2.0) { points[i].x -= surface.UPeriod; } if ((points[i].x - points[i - 1].x) < -surface.UPeriod / 2.0) { points[i].x += surface.UPeriod; } } } if (surface.IsVPeriodic) { for (int i = 1; i < points.Length; i++) { if ((points[i].y - points[i - 1].y) > surface.VPeriod / 2.0) { points[i].y -= surface.VPeriod; } if ((points[i].y - points[i - 1].y) < -surface.VPeriod / 2.0) { points[i].y += surface.VPeriod; } } } if (!periodicDomain.IsEmpty()) { SurfaceHelper.AdjustPeriodic(surface, periodicDomain, points); } }
private int debugCount; // to identify instance when debugging #endif public ProjectedCurve(ICurve curve3D, ISurface surface, bool forward, BoundingRect domain, double precision = 0.0) { #if DEBUG debugCount = debugCounter++; #endif this.curve3D = curve3D; // keep in mind, the curve is not cloned, curve3D should not be modified after this this.surface = surface; List <GeoPoint> lpoles = new List <GeoPoint>(); List <GeoPoint2D> lpoles2d = new List <GeoPoint2D>(); GeoPoint2D cnt2d = domain.GetCenter(); GeoPoint sp = curve3D.StartPoint; GeoPoint ep = curve3D.EndPoint; double[] us = surface.GetUSingularities(); double prec = precision; if (prec == 0.0) { prec = curve3D.Length * 1e-3; // changed to 1e-3, it is used to snap endpoints to poles } startPoint2d = surface.PositionOf(curve3D.StartPoint); endPoint2d = surface.PositionOf(curve3D.EndPoint); bool distinctStartEndPoint = false; if ((surface.IsUPeriodic && Math.Abs(startPoint2d.x - endPoint2d.x) < surface.UPeriod * 1e-3) || (surface.IsVPeriodic && Math.Abs(startPoint2d.y - endPoint2d.y) < surface.VPeriod * 1e-3)) { // adjust start and endpoint according to its neighbors GeoPoint2D p2d = surface.PositionOf(curve3D.PointAt(0.1)); SurfaceHelper.AdjustPeriodic(surface, periodicDomain, ref p2d); BoundingRect ext = new BoundingRect(p2d); SurfaceHelper.AdjustPeriodic(surface, ext, ref startPoint2d); p2d = surface.PositionOf(curve3D.PointAt(0.9)); SurfaceHelper.AdjustPeriodic(surface, periodicDomain, ref p2d); ext = new BoundingRect(p2d); SurfaceHelper.AdjustPeriodic(surface, ext, ref endPoint2d); distinctStartEndPoint = true; } periodicDomain = domain; if (periodicDomain.IsEmpty() && (surface.IsUPeriodic || surface.IsVPeriodic)) { // make a few points and assure that they don't jump over the periodic seam // if the curve3d doesn't jump around wildly, this should work. Maybe use curve3D.GetSavePositions? GeoPoint2D[] point2Ds = new GeoPoint2D[11]; for (int i = 0; i < 11; i++) { point2Ds[i] = surface.PositionOf(curve3D.PointAt(i / 10.0)); } for (int i = 0; i < 10; i++) { GeoVector2D offset = GeoVector2D.NullVector; if (surface.IsUPeriodic && Math.Abs(point2Ds[i + 1].x - point2Ds[i].x) > surface.UPeriod / 2.0) { if ((point2Ds[i + 1].x - point2Ds[i].x) < 0) { offset.x = surface.UPeriod; } else { offset.x = -surface.UPeriod; } } if (surface.IsVPeriodic && Math.Abs(point2Ds[i + 1].y - point2Ds[i].y) > surface.VPeriod / 2.0) { if ((point2Ds[i + 1].y - point2Ds[i].y) < 0) { offset.y = surface.VPeriod; } else { offset.y = -surface.VPeriod; } } point2Ds[i + 1] += offset; } for (int i = 0; i < 11; i++) { periodicDomain.MinMax(point2Ds[i]); } startPoint2d = point2Ds[0]; endPoint2d = point2Ds[10]; } if (!periodicDomain.IsEmpty() && (!surface.IsUPeriodic || periodicDomain.Width < surface.UPeriod * (1 - 1e-6)) && (!surface.IsVPeriodic || periodicDomain.Height < surface.VPeriod * (1 - 1e-6))) { SurfaceHelper.AdjustPeriodic(surface, periodicDomain, ref startPoint2d); SurfaceHelper.AdjustPeriodic(surface, periodicDomain, ref endPoint2d); } startPointIsPole = endPointIsPole = false; for (int i = 0; i < us.Length; i++) { GeoPoint pl = surface.PointAt(new GeoPoint2D(us[i], cnt2d.y)); if ((pl | sp) < prec) { GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.1)); startPoint2d = new GeoPoint2D(us[i], tmp.y); startPointIsPole = true; spu = true; } if ((pl | ep) < prec) { GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.9)); endPoint2d = new GeoPoint2D(us[i], tmp.y); endPointIsPole = true; epu = true; } } double[] vs = surface.GetVSingularities(); for (int i = 0; i < vs.Length; i++) { GeoPoint pl = surface.PointAt(new GeoPoint2D(cnt2d.x, vs[i])); if ((pl | sp) < prec) { GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.1)); startPoint2d = new GeoPoint2D(tmp.x, vs[i]); startPointIsPole = true; spu = false; } if ((pl | ep) < prec) { GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.9)); endPoint2d = new GeoPoint2D(tmp.x, vs[i]); endPointIsPole = true; epu = false; } } if (forward) { startParam = 0.0; endParam = 1.0; } else { startParam = 1.0; endParam = 0.0; } #if DEBUG this.MakeTriangulation(); #endif }
internal void CenterPatch(LayoutPatch patch, double scale, HorizontalCenter hor, VerticalCenter ver) { // die Projektion ist ja zwei Anteile, unscaledProjection hält immer den Nullpunkt // fest und skaliert nicht, und Placement platziert BoundingRect areaext; if (patch.Area != null) { areaext = patch.Area.Extent; } else { areaext = new BoundingRect(0.0, 0.0, paperWidth, paperHeight); } BoundingRect modelext = patch.Model.GetExtent(patch.Projection); if (modelext.IsEmpty()) { return; } GeoPoint2D modelcnt = modelext.GetCenter(); GeoPoint2D areacnt = areaext.GetCenter(); double factor, dx, dy; patch.Projection.GetPlacement(out factor, out dx, out dy); if (scale != 0.0) { factor = scale; } switch (hor) { case HorizontalCenter.left: dx = areaext.Left - (modelext.Left * factor); break; case HorizontalCenter.center: dx = areacnt.x - (modelcnt.x * factor); break; case HorizontalCenter.right: dx = areaext.Right - (modelext.Right * factor); break; default: break; } switch (ver) { case VerticalCenter.bottom: dy = areaext.Bottom - (modelext.Bottom * factor); break; case VerticalCenter.center: dy = areacnt.y - (modelcnt.y * factor); break; case VerticalCenter.top: dy = areaext.Top - (modelext.Top * factor); break; default: break; } patch.Projection.SetPlacement(factor, dx, dy); }