// // Summary: // Translates the specified System.Windows.Point by the specified System.Windows.Vector // and returns the result. // // Parameters: // point: // The point to translate. // // vector: // The amount by which to translate point. // // Returns: // The result of translating the specified point by the specified vector. public static PointHelper operator +(PointHelper point, Vector vector) { var result = new PointHelper(); result._value.X = vector.X + point.Value.X; result._value.Y = vector.Y + point.Value.Y; return result; }
private void FlattenArc(List<Point> points, Point pt1, Point pt2, double radiusX, double radiusY, double angleRotation, bool isLargeArc, bool isCounterclockwise, double tolerance) { // Adjust for different radii and rotation angle #if SILVERLIGHT var matx = new MatrixHelper(); matx.Rotate(-angleRotation); matx.Scale(radiusY / radiusX, 1); pt1 = matx.Value.Transform(pt1); pt2 = matx.Value.Transform(pt2); #else Matrix matx = new Matrix(); matx.Rotate(-angleRotation); matx.Scale(radiusY / radiusX, 1); pt1 = matx.Transform(pt1); pt2 = matx.Transform(pt2); #endif // Get info about chord that connects both points var midPoint = new Point((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2); #if SILVERLIGHT Vector vect = new PointHelper(pt2) - new PointHelper(pt1); #else Vector vect = pt2 - pt1; #endif double halfChord = vect.Length / 2; // Get vector from chord to center Vector vectRotated; // (comparing two Booleans here!) vectRotated = isLargeArc == isCounterclockwise ? new Vector(-vect.Y, vect.X) : new Vector(vect.Y, -vect.X); vectRotated.Normalize(); // Distance from chord to center double centerDistance = Math.Sqrt(radiusY * radiusY - halfChord * halfChord); // Calculate two center points Point center = midPoint + centerDistance * vectRotated; // Get angles from center to the two points double angle1 = Math.Atan2(pt1.Y - center.Y, pt1.X - center.X); double angle2 = Math.Atan2(pt2.Y - center.Y, pt2.X - center.X); // (another comparison of two Booleans!) if (isLargeArc == (Math.Abs(angle2 - angle1) < Math.PI)) { if (angle1 < angle2) angle1 += 2 * Math.PI; else angle2 += 2 * Math.PI; } // Invert matrix for final point calculation matx.Invert(); // Calculate number of points for polyline approximation var max = (int)((4 * (radiusX + radiusY) * Math.Abs(angle2 - angle1) / (2 * Math.PI)) / tolerance); // Loop through the points for (int i = 0; i <= max; i++) { double angle = ((max - i) * angle1 + i * angle2) / max; double x = center.X + radiusY * Math.Cos(angle); double y = center.Y + radiusY * Math.Sin(angle); // Transform the point back Point pt = matx.Transform(new Point(x, y)); points.Add(pt); } }