// ------------------------------------------------- // Util // ------------------------------------------------- private static Geometry.Interval RelativeEnvelopeLon(Geometry.IRandomAccessRange <Geometry.Point> points, bool closed, Geometry.Unit unit) { Geometry.Interval result = null; if (points.Count < 1) { result = new Geometry.Interval(); Geometry.AssignInverse(result); return(result); } double x0 = points[0][0]; result = new Geometry.Interval(x0); int count = points.Count + (closed ? 1 : 0); for (int ii = 1; ii < count; ++ii) { int i = ii % points.Count; double xi = points[i][0]; double distNorm = Geometry.NormalizedAngleSigned(xi - x0, unit); // [-pi, pi] double x1 = x0 + distNorm; result.Expand(x1); x0 = x1; } return(result); }
public PeriodicDrawableBox(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, Geometry.Unit unit) : base(true) { int count = points.Count + 1; xs_orig = new float[count]; points_rel = new PointF[count]; xs_orig[0] = cs.ConvertX(points[0][0]); points_rel[0] = cs.Convert(points[0]); for (int i = 1; i < points.Count; ++i) { xs_orig[i] = cs.ConvertX(points[i][0]); // always relative to p0 double distNorm = Geometry.NormalizedAngleUnsigned(points[i][0] - points[0][0], unit); // [0, 2pi] - min is always lesser than max double x_curr = points[0][0] + distNorm; // always relative to p0 points_rel[i] = new PointF(cs.ConvertX(x_curr), cs.ConvertY(points[i][1])); } // close xs_orig[points.Count] = xs_orig[0]; points_rel[points.Count] = points_rel[0]; }
public PeriodicDrawablePolygon(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> outer, IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners, Geometry.Box box, Geometry.Unit unit) { this.outer = new PeriodicDrawableRange(cs, outer, box, unit); minf = this.outer.minf; maxf = this.outer.maxf; periodf = this.outer.periodf; box_minf = this.outer.box_minf; box_maxf = this.outer.box_maxf; this.inners = new List <PeriodicDrawableRange>(); int i = 0; foreach (var inner in inners) { this.inners.Add(new PeriodicDrawableRange(cs, inner, box, unit)); // expand relative box X if (this.inners[i].minf < minf) { minf = this.inners[i].minf; } if (this.inners[i].maxf > maxf) { maxf = this.inners[i].maxf; } } }
public static Geometry.Interval RelativeEnvelopeLon(Geometry.IRandomAccessRange <Geometry.Point> outer, IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners, Geometry.Unit unit) { Geometry.Interval result = RelativeEnvelopeLon(outer, true, unit); foreach (var inner in inners) { result.Expand(RelativeEnvelopeLon(inner, true, unit)); } return(result); }
public PeriodicDrawableRange(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, Geometry.Box box, Geometry.Unit unit) { if (points.Count < 2) { return; } double pi = Geometry.HalfAngle(unit); periodf = cs.ConvertDimension(2 * pi); xs_orig = new float[points.Count]; points_rel = new PointF[points.Count]; xs_orig[0] = cs.ConvertX(points[0][0]); points_rel[0] = cs.Convert(points[0]); minf = points_rel[0].X; maxf = points_rel[0].X; double x0 = Geometry.NormalizedAngle(points[0][0], unit); double x0_prev = points[0][0]; for (int i = 1; i < points.Count; ++i) { xs_orig[i] = cs.ConvertX(points[i][0]); double x1 = Geometry.NormalizedAngle(points[i][0], unit); double dist = x1 - x0; // [-2pi, 2pi] double distNorm = Geometry.NormalizedAngle(dist, unit); // [-pi, pi] double x0_curr = x0_prev + distNorm; points_rel[i] = new PointF(cs.ConvertX(x0_curr), cs.ConvertY(points[i][1])); // expand relative box X if (points_rel[i].X < minf) { minf = points_rel[i].X; } if (points_rel[i].X > maxf) { maxf = points_rel[i].X; } x0_prev = x0_curr; x0 = x1; } box_minf = cs.ConvertX(box.Min[0]); box_maxf = cs.ConvertX(box.Max[0]); }
public PeriodicDrawablePolygon(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> outer, IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners, Geometry.Unit unit, bool densify) { this.outer = new PeriodicDrawableRange(cs, outer, true, unit, densify); this.inners = new List <PeriodicDrawableRange>(); foreach (var inner in inners) { PeriodicDrawableRange pd = new PeriodicDrawableRange(cs, inner, true, unit, densify); this.inners.Add(pd); } }
public PeriodicDrawableBox(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, Geometry.Box box, Geometry.Unit unit) { double pi = Geometry.HalfAngle(unit); periodf = cs.ConvertDimension(2 * pi); xs_orig = new float[points.Count]; points_rel = new PointF[points.Count]; xs_orig[0] = cs.ConvertX(points[0][0]); points_rel[0] = cs.Convert(points[0]); minf = points_rel[0].X; maxf = points_rel[0].X; double x0 = Geometry.NormalizedAngle(points[0][0], unit); for (int i = 1; i < points.Count; ++i) { xs_orig[i] = cs.ConvertX(points[i][0]); double x1 = Geometry.NormalizedAngle(points[i][0], unit); double dist = x1 - x0; // [-2pi, 2pi] double distNorm = Geometry.NormalizedAngle(dist, unit); // [-pi, pi] while (distNorm < 0) { distNorm += 2 * Geometry.HalfAngle(unit); // [0, 2pi] - min is always lesser than max } double x0_curr = points[0][0] + distNorm; // always relative to p0 points_rel[i] = new PointF(cs.ConvertX(x0_curr), cs.ConvertY(points[i][1])); // expand relative box X if (points_rel[i].X < minf) { minf = points_rel[i].X; } if (points_rel[i].X > maxf) { maxf = points_rel[i].X; } } box_minf = cs.ConvertX(box.Min[0]); box_maxf = cs.ConvertX(box.Max[0]); }
public PointF[] Convert(Geometry.IRandomAccessRange <Geometry.Point> points) { if (points.Count <= 0) { return(null); } int dst_count = points.Count + (points[0] == points[points.Count - 1] ? 0 : 1); PointF[] dst_points = new PointF[dst_count]; int i = 0; for (; i < points.Count; ++i) { dst_points[i] = Convert(points[i]); } if (i < dst_count) { dst_points[i] = Convert(points[0]); } return(dst_points); }
public PeriodicDrawableRange(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, bool closed, Geometry.Unit unit, bool densify) { this.closed = closed; this.containsPole = ContainsPole.No; if (points.Count < 2) { return; } // approx. length of densified segments /*double densLength = Math.Min(cs.InverseConvertDimensionX(20), * cs.InverseConvertDimensionY(20));*/ double densLength = Geometry.FromDegree(5, unit); int count = points.Count + (closed ? 1 : 0); xs_orig = new float[count]; points_rel = new PointF[count]; if (densify) { dens_points_rel = new PointF[points.Count][]; } xs_orig[0] = cs.ConvertX(points[0][0]); points_rel[0] = cs.Convert(points[0]); Geometry.Point p0 = points[0].Clone(); for (int i = 1; i < count; ++i) { Geometry.Point p1 = points[i % points.Count].Clone(); xs_orig[i] = cs.ConvertX(p1[0]); double distNorm = Geometry.NormalizedAngleSigned(p1[0] - p0[0], unit); // [-pi, pi] p1[0] = p0[0] + distNorm; points_rel[i] = cs.Convert(p1); if (dens_points_rel != null) { dens_points_rel[i - 1] = DensifyAndConvert(cs, p0, p1, densLength, unit); } p0 = p1; } if (closed && Math.Abs(points_rel[0].X - points_rel[points.Count].X) > 0.1) { // Check which pole double area = 0; p0 = points[0].Clone(); for (int i = 1; i < count; ++i) { Geometry.Point p1 = points[i % points.Count].Clone(); double distNorm = Geometry.NormalizedAngleSigned(p1[0] - p0[0], unit); // [-pi, pi] p1[0] = p0[0] + distNorm; area += Geometry.SphericalTrapezoidArea(p0, p1, unit); p0 = p1; } int areaSign = Math.Sign(area); int dirSign = Math.Sign(points_rel[points.Count].X - points_rel[0].X); this.containsPole = (areaSign * dirSign >= 0) ? ContainsPole.North : ContainsPole.South; } }
private static Geometry.Box AabbRange(Geometry.IRandomAccessRange <Geometry.Point> rng, bool closed, Geometry.Traits traits, bool calculateEnvelope) { return(calculateEnvelope ? Geometry.Envelope(rng, closed, traits) : Geometry.Aabb(rng, closed, traits.Unit)); }