private void CreatePolygonPath() { var points = (float)Math.Floor(_pointsAnimation.Value.Value); double currentAngle = _rotationAnimation?.Value ?? 0f; // Start at +y instead of +x currentAngle -= 90; // convert to radians currentAngle = MathExt.ToRadians(currentAngle); // adjust current angle for partial points var anglePerPoint = (float)(2 * Math.PI / points); var roundedness = _outerRoundednessAnimation.Value.Value / 100f; var radius = _outerRadiusAnimation.Value.Value; float x; float y; x = (float)(radius * Math.Cos(currentAngle)); y = (float)(radius * Math.Sin(currentAngle)); _path.MoveTo(x, y); currentAngle += anglePerPoint; var numPoints = (int)Math.Ceiling(points); for (var i = 0; i < numPoints; i++) { var previousX = x; var previousY = y; x = (float)(radius * Math.Cos(currentAngle)); y = (float)(radius * Math.Sin(currentAngle)); if (roundedness != 0) { var cp1Theta = (float)(Math.Atan2(previousY, previousX) - Math.PI / 2f); var cp1Dx = (float)Math.Cos(cp1Theta); var cp1Dy = (float)Math.Sin(cp1Theta); var cp2Theta = (float)(Math.Atan2(y, x) - Math.PI / 2f); var cp2Dx = (float)Math.Cos(cp2Theta); var cp2Dy = (float)Math.Sin(cp2Theta); var cp1X = radius * roundedness * PolygonMagicNumber * cp1Dx; var cp1Y = radius * roundedness * PolygonMagicNumber * cp1Dy; var cp2X = radius * roundedness * PolygonMagicNumber * cp2Dx; var cp2Y = radius * roundedness * PolygonMagicNumber * cp2Dy; _path.CubicTo(previousX - cp1X, previousY - cp1Y, x + cp2X, y + cp2Y, x, y); } else { _path.LineTo(x, y); } currentAngle += anglePerPoint; } var position = _positionAnimation.Value; if (position != null) { _path.Offset(position.X, position.Y); } _path.Close(); }
private void CreateStarPath() { var points = _pointsAnimation.Value.Value; double currentAngle = _rotationAnimation?.Value ?? 0f; // Start at +y instead of +x currentAngle -= 90; // convert to radians currentAngle = MathExt.ToRadians(currentAngle); // adjust current angle for partial points var anglePerPoint = (float)(2 * Math.PI / points); var halfAnglePerPoint = anglePerPoint / 2.0f; var partialPointAmount = points - (int)points; if (partialPointAmount != 0) { currentAngle += halfAnglePerPoint * (1f - partialPointAmount); } var outerRadius = _outerRadiusAnimation.Value.Value; var innerRadius = _innerRadiusAnimation.Value.Value; var innerRoundedness = 0f; if (_innerRoundednessAnimation != null) { innerRoundedness = _innerRoundednessAnimation.Value.Value / 100f; } var outerRoundedness = 0f; if (_outerRoundednessAnimation != null) { outerRoundedness = _outerRoundednessAnimation.Value.Value / 100f; } float x; float y; float partialPointRadius = 0; if (partialPointAmount != 0) { partialPointRadius = innerRadius + partialPointAmount * (outerRadius - innerRadius); x = (float)(partialPointRadius * Math.Cos(currentAngle)); y = (float)(partialPointRadius * Math.Sin(currentAngle)); _path.MoveTo(x, y); currentAngle += anglePerPoint * partialPointAmount / 2f; } else { x = (float)(outerRadius * Math.Cos(currentAngle)); y = (float)(outerRadius * Math.Sin(currentAngle)); _path.MoveTo(x, y); currentAngle += halfAnglePerPoint; } // True means the line will go to outer radius. False means inner radius. var longSegment = false; var numPoints = (int)Math.Ceiling(points) * 2; for (var i = 0; i < numPoints; i++) { var radius = longSegment ? outerRadius : innerRadius; var dTheta = halfAnglePerPoint; if (partialPointRadius != 0 && i == numPoints - 2) { dTheta = anglePerPoint * partialPointAmount / 2f; } if (partialPointRadius != 0 && i == numPoints - 1) { radius = partialPointRadius; } var previousX = x; var previousY = y; x = (float)(radius * Math.Cos(currentAngle)); y = (float)(radius * Math.Sin(currentAngle)); if (innerRoundedness == 0 && outerRoundedness == 0) { _path.LineTo(x, y); } else { var cp1Theta = (float)(Math.Atan2(previousY, previousX) - Math.PI / 2f); var cp1Dx = (float)Math.Cos(cp1Theta); var cp1Dy = (float)Math.Sin(cp1Theta); var cp2Theta = (float)(Math.Atan2(y, x) - Math.PI / 2f); var cp2Dx = (float)Math.Cos(cp2Theta); var cp2Dy = (float)Math.Sin(cp2Theta); var cp1Roundedness = longSegment ? innerRoundedness : outerRoundedness; var cp2Roundedness = longSegment ? outerRoundedness : innerRoundedness; var cp1Radius = longSegment ? innerRadius : outerRadius; var cp2Radius = longSegment ? outerRadius : innerRadius; var cp1X = cp1Radius * cp1Roundedness * PolystarMagicNumber * cp1Dx; var cp1Y = cp1Radius * cp1Roundedness * PolystarMagicNumber * cp1Dy; var cp2X = cp2Radius * cp2Roundedness * PolystarMagicNumber * cp2Dx; var cp2Y = cp2Radius * cp2Roundedness * PolystarMagicNumber * cp2Dy; if (partialPointAmount != 0) { if (i == 0) { cp1X *= partialPointAmount; cp1Y *= partialPointAmount; } else if (i == numPoints - 1) { cp2X *= partialPointAmount; cp2Y *= partialPointAmount; } } _path.CubicTo(previousX - cp1X, previousY - cp1Y, x + cp2X, y + cp2Y, x, y); } currentAngle += dTheta; longSegment = !longSegment; } var position = _positionAnimation.Value; if (position != null) { _path.Offset(position.X, position.Y); } _path.Close(); }
public void AddPathSegment(SKPath canvasPathBuilder, ref bool closed) { canvasPathBuilder.ArcTo(_endPoint.ToSkPoint(), (float)MathExt.ToRadians(_sweepAngle), SKPathArcSize.Small, SKPathDirection.Clockwise, new SKPoint(_a, _b)); closed = false; }
public override ScaleXy GetValue(IKeyframe <ScaleXy> keyframe, float keyframeProgress) { if (keyframe.StartValue == null || keyframe.EndValue == null) { throw new InvalidOperationException("Missing values for keyframe."); } var startTransform = keyframe.StartValue; var endTransform = keyframe.EndValue; return(new ScaleXy(MathExt.Lerp(startTransform.ScaleX, endTransform.ScaleX, keyframeProgress), MathExt.Lerp(startTransform.ScaleY, endTransform.ScaleY, keyframeProgress))); }
public void AddPathSegment(ref CanvasGeometry geometry, CanvasPathBuilder canvasPathBuilder, CanvasDevice device, ref bool closed) { canvasPathBuilder.AddArc(_endPoint, _a, _b, (float)MathExt.ToRadians(_sweepAngle), CanvasSweepDirection.Clockwise, CanvasArcSize.Small); closed = false; }