public virtual void DrawPointFrame(SKSurface surface, List <AnimatedPoint> pointChanges) { using (var canvas = surface.Canvas) { canvas.Clear(); //case in frame immediately after animation has completed, nothing needs to be drawn if (CurrentFrame > NumFrames) { return; } //vertex and its original vertex in InternalPoints var updatedPoints = new Tuple <Vertex, Vertex> [InternalPoints.Count]; //for quick lookup to check if a specified point index has been modified var updatedIndices = new int[pointChanges.Count]; for (var i = 0; i < pointChanges.Count; i++) { var animatedPoint = pointChanges[i]; //find index of animated point in InternalPoints var index = InternalPoints.FindIndex(v => v.x.Equals(animatedPoint.Point.X) && v.y.Equals(animatedPoint.Point.Y)); //only malloc if null or item2 is different if (updatedPoints[index] != null && updatedPoints[index].Item2.Equals(InternalPoints[index])) { updatedPoints[index].Item1.x = animatedPoint.Point.X + animatedPoint.XDisplacement; updatedPoints[index].Item1.y = animatedPoint.Point.Y + animatedPoint.YDisplacement; } else { updatedPoints[index] = new Tuple <Vertex, Vertex>( new Vertex(animatedPoint.Point.X + animatedPoint.XDisplacement, animatedPoint.Point.Y + animatedPoint.YDisplacement), InternalPoints[index]); } //mark this point's index as used updatedIndices[i] = index; } //increment updated points foreach (var updatedPoint in updatedPoints) { //non-updated points will be null if (updatedPoint == null) { continue; } //increment each triad that contains this updatedPoint foreach (var tri in InternalPointToTriangleDic[updatedPoint.Item2]) { GetCorrectPoint(updatedPoints, updatedIndices, tri.a, ref PathPointA); GetCorrectPoint(updatedPoints, updatedIndices, tri.b, ref PathPointB); GetCorrectPoint(updatedPoints, updatedIndices, tri.c, ref PathPointC); Geometry.centroid(tri, InternalPoints, ref Center); //triangle color center CurrentTriangulation.KeepInBounds(ref Center); fillPaint.Color = CurrentTriangulation.GetTriangleColor(Center); Geometry.DrawTrianglePath(ref TrianglePath, PathPointA, PathPointB, PathPointC); canvas.DrawPath(TrianglePath, fillPaint); if (HideLines) { //need to maintain the strokepaint reguardless if we are just hiding its display var backup = strokePaint.Color; strokePaint.Color = fillPaint.Color; canvas.DrawPath(TrianglePath, strokePaint); strokePaint.Color = backup; } else { canvas.DrawPath(TrianglePath, strokePaint); } } } } }