/// <summary> /// Reduce list of points, so that all are inside of cliptRect /// See https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm /// </summary> /// <param name="points">List of points to reduce</param> /// <param name="viewport">Viewport implementation</param> /// <param name="clipRect">Rectangle to clip to. All points outside aren't drawn.</param> /// <returns></returns> public static List <SKPoint> ReducePointsToClipRect(IEnumerable <Coordinate>?points, IReadOnlyViewport viewport, SKRect clipRect) { var output = WorldToScreen(viewport, points); // Do this for the 4 edges (left, top, right, bottom) of clipping rectangle for (var j = 0; j < 4; j++) { // If there aren't any points to reduce if (output.Count == 0) { return(new List <SKPoint>()); } // New input list is the last output list of points var input = new List <SKPoint>(output); output.Clear(); var pointStart = input.Last(); foreach (var pointEnd in input) { // Is pointEnd inside of clipping rectangle regarding this edge if (Comparer[j](pointEnd, clipRect)) { // Is pointStart outside of clipping rectangle regarding this edge if (!Comparer[j](pointStart, clipRect)) { // Yes, than line is coming from outside to inside, so calculate intersection output.Add(Intersecter[j](pointStart, pointEnd, clipRect)); } // pointEnd is inside, so add it to points list output.Add(pointEnd); } // Is pointStart inside of clipping rectangle regarding this edge else if (Comparer[j](pointStart, clipRect)) { // Yes, than line is coming from inside to outside, so calculate intersection output.Add(Intersecter[j](pointStart, pointEnd, clipRect)); } // Set next pointStart pointStart = pointEnd; } } return(output); }
public static BoundaryMesh <T> ComputeMesh <T>(IList <T> nodeList, Settings settings) where T : IMesherNode, new() { // Create Voronoi mesh // ================================= IEnumerator <Line> boundaryLines = Line.GetEnumerator(settings.Boundary); IntersectionMesh <T> mesh = null; for (int iLloyd = 0; iLloyd <= settings.NumberOfLloydIterations; ++iLloyd) { // Mesh generation //------------------------------------- AddDistantBoundingNodes(nodeList, settings.BoundingBox); mesh = IntersectionMeshGenerator.CreateMesh(nodeList, settings.FirstCellNode_indice); //Clip //------------------------------------- Intersecter.Intersect(mesh, boundaryLines); // Lloyds algorithm (Voronoi relaxation) // ------------------------------------- IReadOnlyList <MeshCell <T> > cells = mesh.GetCells(); //GetInsideCell : Return Cells in order of MeshArray. if (iLloyd != settings.NumberOfLloydIterations) { MoveNodesTowardsCellCenter(cells, ref settings.FirstCellNode_indice); } nodeList = mesh.GetNodes(); } return(mesh); }
public override void Evaluate(ref IResultSet <KeyValuePair <AttributeValue, long> > resultSet, QueryCriteria values) { if (resultSet == null) { resultSet = new ListedResultSet <KeyValuePair <AttributeValue, long> >(); } IDictionary <long, AttributeValue> initial = new HashVector <long, AttributeValue>(); var firstIteration = true; var intersecter = new Intersecter <long, AttributeValue>(initial); if (_childPredicates != null) { foreach (var predicate in _childPredicates) { var terminal = (TerminalPredicate)predicate; if (terminal == null) { continue; } foreach (var kvp in terminal.Enumerate(values)) { if (firstIteration) { initial[kvp.Value] = kvp.Key; } else { intersecter.Add(kvp.Value, kvp.Key); } } if (!firstIteration) { intersecter.Flip(); } firstIteration = false; } } foreach (var keyValuePair in intersecter.FinalResult) { resultSet.Add(new KeyValuePair <AttributeValue, long>(keyValuePair.Value, keyValuePair.Key)); } }