private InsetVertex CombineVectorLines(InsetVertex prev, InsetVertex next, double thickness) { var prevLine = new LineF(prev.Previous, prev.Outer); var nextLine = new LineF(next.Outer, next.Next); var newOuter = prevLine.Intersect(nextLine); return(new InsetVertex(newOuter, prev.Previous, next.Next, thickness)); }
private bool DoesIntersect(InsetVertex one, InsetVertex two) { return(!IsSameSign(Cross(one.Inner - one.Outer, two.Outer - one.Inner), Cross(one.Inner - one.Outer, two.Inner - one.Inner)) && !IsSameSign(Cross(two.Inner - two.Outer, one.Outer - two.Inner), Cross(two.Inner - two.Outer, one.Inner - two.Inner))); }
private int PopulatePolyStorage(List <Vector2> polygon, double thickness = 0) { if (polygon.Count < 3) { return(0); } if (_polyStorage == null || _polyStorage.Length < polygon.Count) { _polyStorage = new InsetVertex[polygon.Count]; } if (Math.Abs(thickness) < _doubleCheckCushion) { for (var i = 0; i < polygon.Count; i++) { _polyStorage[i] = new InsetVertex(polygon[i]); } return(polygon.Count); } var storageLength = 0; for (var i = 0; i < polygon.Count; i++) { var current = polygon[i]; var prevPoint = polygon[(i - 1 + polygon.Count) % polygon.Count]; var nextPoint = polygon[(i + 1) % polygon.Count]; var lineToInner = new InsetVertex(current, prevPoint, nextPoint, thickness); if (storageLength > 0 && thickness > 0 && DoesIntersect(_polyStorage[storageLength - 1], lineToInner)) { _polyStorage[storageLength - 1] = CombineVectorLines(_polyStorage[storageLength - 1], lineToInner, thickness); } else { _polyStorage[storageLength] = lineToInner; storageLength += 1; } } if (thickness > 0) { var numInvalidated = 0; for (var i = 0; i < storageLength; i++) { var current = _polyStorage[i]; var prevIndex = (i - 1 + storageLength) % storageLength; var prev = _polyStorage[prevIndex]; if (DoesIntersect(prev, current)) { _polyStorage[i] = CombineVectorLines(prev, current, thickness); // Optimizing for the most common case if (prevIndex == 0) { storageLength -= 1; } else { _polyStorage[prevIndex] = new InsetVertex(Vector2.Zero, false); numInvalidated += 1; } } else { break; } } if (storageLength - numInvalidated < 3) { return(0); } if (numInvalidated > 0) { for (var i = 0; i < storageLength; i++) { if (!_polyStorage[i].IsValid) { for (var j = i + 1; j < storageLength; j++) { _polyStorage[j - 1] = _polyStorage[j]; } storageLength -= 1; i -= 1; } } } } return(storageLength); }