public MonotoneBox(Vertex2D vertex1, Vertex2D vertex2, MonotonicityChange lowMonoChange, MonotonicityChange hiMonoChange, bool xInPositiveMonotonicity, bool yInPositiveMonotonicity) : this() { this.Vertex1 = vertex1; this.Vertex2 = vertex2; this.LowChange = lowMonoChange; this.HiChange = hiMonoChange; XInPositiveMonotonicity = xInPositiveMonotonicity; YInPositiveMonotonicity = yInPositiveMonotonicity; Left = Math.Min(vertex1.X, vertex2.X); Right = Math.Max(vertex1.X, vertex2.X); Bottom = Math.Min(vertex1.Y, vertex2.Y); Top = Math.Max(vertex1.Y, vertex2.Y); }
public MonotoneBox(IList <PointLight> p, int lowIndex, int hiIndex, MonotonicityChange lowMonoChange, MonotonicityChange hiMonoChange, int xDirection, int yDirection) : this() { this.LowIndex = lowIndex; this.HiIndex = hiIndex; this.LowChange = lowMonoChange; this.HiChange = hiMonoChange; XInPositiveMonotonicity = xDirection > 0; YInPositiveMonotonicity = yDirection > 0; Left = Math.Min(p[lowIndex].X, p[hiIndex].X); Right = Math.Max(p[lowIndex].X, p[hiIndex].X); Bottom = Math.Min(p[lowIndex].Y, p[hiIndex].Y); Top = Math.Max(p[lowIndex].Y, p[hiIndex].Y); }
/// <summary> /// Partitions the into monotone boxes. /// </summary> /// <param name="polygon">The polygon.</param> /// <param name="divideAt">The divide at.</param> /// <returns>System.Collections.Generic.IEnumerable<TVGL.TwoDimensional.MonotoneBox>.</returns> /// <exception cref="MonotoneBox">polygon.Vertices[0], polygon.Vertices[1], MonotonicityChange.Both, MonotonicityChange.Both, true, true</exception> public static IEnumerable <MonotoneBox> PartitionIntoMonotoneBoxes(this Polygon polygon, MonotonicityChange divideAt = MonotonicityChange.Both) { polygon.MakePolygonEdgesIfNonExistent(); var numPoints = polygon.Vertices.Count; if (numPoints <= 1) { yield return (new MonotoneBox(polygon.Vertices[0], polygon.Vertices[0], MonotonicityChange.Both, MonotonicityChange.Both, true, true)); yield break; } if (numPoints <= 2) { yield return (new MonotoneBox(polygon.Vertices[0], polygon.Vertices[1], MonotonicityChange.Both, MonotonicityChange.Both, true, true)); yield break; } var initBoxIndex = -1; var initBoxMonoChange = MonotonicityChange.Neither; Vertex2D beginBoxVertex = null; var beginBoxMonoChange = MonotonicityChange.Neither; var tolerance = polygon.GetToleranceForPolygon(); var i = 0; while (i % numPoints != initBoxIndex) { var vertex = polygon.Vertices[i % numPoints]; var monoChange = GetMonotonicityChange(vertex, tolerance); if (monoChange == MonotonicityChange.SameAsPrevious || monoChange == MonotonicityChange.Neither) { continue; } if (monoChange == MonotonicityChange.Both || (monoChange == MonotonicityChange.X && (divideAt == MonotonicityChange.X || divideAt == MonotonicityChange.Both)) || (monoChange == MonotonicityChange.Y && (divideAt == MonotonicityChange.Y || divideAt == MonotonicityChange.Both))) { if (initBoxIndex < 0) { initBoxIndex = i; beginBoxVertex = vertex; initBoxMonoChange = beginBoxMonoChange = monoChange; } else { yield return(new MonotoneBox(beginBoxVertex, vertex, beginBoxMonoChange, monoChange, vertex.X >= beginBoxVertex.X, vertex.Y >= beginBoxVertex.Y)); beginBoxVertex = vertex; beginBoxMonoChange = monoChange; } } i++; } var lastVertex = polygon.Vertices[initBoxIndex]; yield return(new MonotoneBox(beginBoxVertex, lastVertex, beginBoxMonoChange, initBoxMonoChange, lastVertex.X - beginBoxVertex.X >= 0, lastVertex.Y - beginBoxVertex.Y >= 0)); }