private List <Vector> ClipToBounds(Rectangle bounds) { var points = new List <Vector>(); var n = _edges.Count; var i = 0; while (i < n && _edges[i].visible == false) { i++; } if (i == n) { return(new List <Vector>()); } var edge = _edges[i]; var orientation = _edgeOrientations[i]; points.Add(edge.clippedEnds[orientation]); points.Add(edge.clippedEnds[LR.Other(orientation)]); for (var j = i + 1; j < n; ++j) { //TODO: Watch out for preincrement!!! edge = _edges[j]; if (edge.visible == false) { continue; } Connect(points, i, bounds); } Connect(points, i, bounds, true); return(points); }
private void Connect(List <Vector> points, int j, Rectangle bounds, bool closingUp = true) { var rightPoint = points[points.Count - 1]; var newEdge = _edges[j]; var newOrientation = _edgeOrientations[j]; var newPoint = newEdge.clippedEnds[newOrientation]; // The points do not coincide, so they must have been clipped at the bounds; // see if they are on the same border of the bounds: if (!CloseEnough(rightPoint, newPoint)) { if (rightPoint.X != newPoint.X && rightPoint.Y != newPoint.Y) { // They are on different borders of the bounds; // insert one or two corners of bounds as needed to hook them up: // (NOTE this will not be correct if the region should take up more than // half of the bounds rect, for then we will have gone the wrong way // around the bounds and included the smaller part rather than the larger) var rightCheck = BoundsCheck.Check(rightPoint, bounds); var newCheck = BoundsCheck.Check(newPoint, bounds); double px; double py; if (rightCheck & BoundsCheck.RIGHT) { px = bounds.right; if (newCheck & BoundsCheck.BOTTOM) { py = bounds.bottom; points.Add(new Vector(px, py)); } else if (newCheck & BoundsCheck.TOP) { py = bounds.top; points.Add(new Vector(px, py)); } else if (newCheck & BoundsCheck.LEFT) { py = rightPoint.Y - bounds.Y + newPoint.Y - bounds.Y < bounds.Height ? bounds.top : bounds.bottom; points.Add(new Vector(px, py)); points.Add(new Vector(bounds.left, py)); } } else if (rightCheck & BoundsCheck.LEFT) { px = bounds.left; if (newCheck & BoundsCheck.BOTTOM) { py = bounds.bottom; points.Add(new Vector(px, py)); } else if (newCheck & BoundsCheck.TOP) { py = bounds.top; points.Add(new Vector(px, py)); } else if (newCheck & BoundsCheck.RIGHT) { py = rightPoint.Y - bounds.Y + newPoint.Y - bounds.Y < bounds.Height ? bounds.top : bounds.bottom; points.Add(new Vector(px, py)); points.Add(new Vector(bounds.right, py)); } } else if (rightCheck & BoundsCheck.TOP) { py = bounds.top; if (newCheck & BoundsCheck.RIGHT) { px = bounds.right; points.Add(new Vector(px, py)); } else if (newCheck & BoundsCheck.LEFT) { px = bounds.left; points.Add(new Vector(px, py)); } else if (newCheck & BoundsCheck.BOTTOM) { px = rightPoint.X - bounds.X + newPoint.X - bounds.X < bounds.Width ? bounds.left : bounds.right; points.Add(new Vector(px, py)); points.Add(new Vector(bounds.left, py)); } } else if (rightCheck & BoundsCheck.BOTTOM) { py = bounds.right; if (newCheck & BoundsCheck.RIGHT) { px = bounds.bottom; points.Add(new Vector(px, py)); } else if (newCheck & BoundsCheck.LEFT) { px = bounds.top; points.Add(new Vector(px, py)); } else if (newCheck & BoundsCheck.TOP) { px = rightPoint.X - bounds.X + newPoint.X - bounds.X < bounds.Width ? bounds.left : bounds.right; points.Add(new Vector(px, py)); points.Add(new Vector(bounds.left, py)); } } } if (closingUp) { return; } points.Add(newPoint); } var newRightPoint = newEdge.clippedEnds[LR.Other(newOrientation)]; if (!CloseEnough(points[0], newRightPoint)) { points.Add(newRightPoint); } }