public RenderContext(ResourceManager resourceManager, Selector selector, RectangleF tileRect, double scale, MapOptions options, Stylesheet styles, Size tileSize) { this.resourceManager = resourceManager; this.selector = selector; this.tileRect = tileRect; this.scale = scale; this.options = options; this.styles = styles; this.tileSize = tileSize; XMatrix m = new XMatrix(); m.TranslatePrepend((float)(-tileRect.Left * scale * Astrometrics.ParsecScaleX), (float)(-tileRect.Top * scale * Astrometrics.ParsecScaleY)); m.ScalePrepend((float)scale * Astrometrics.ParsecScaleX, (float)scale * Astrometrics.ParsecScaleY); imageSpaceToWorldSpace = m; m.Invert(); worldSpaceToImageSpace = m; }
/// <summary> /// Creates between 1 and 5 Béziers curves from parameters specified like in WPF. /// </summary> public static List<XPoint> BezierCurveFromArc(XPoint point1, XPoint point2, XSize size, double rotationAngle, bool isLargeArc, bool clockwise, PathStart pathStart) { // See also http://www.charlespetzold.com/blog/blog.xml from January 2, 2008: // http://www.charlespetzold.com/blog/2008/01/Mathematics-of-ArcSegment.html double δx = size.Width; double δy = size.Height; Debug.Assert(δx * δy > 0); double factor = δy / δx; bool isCounterclockwise = !clockwise; // Adjust for different radii and rotation angle. XMatrix matrix = new XMatrix(); matrix.RotateAppend(-rotationAngle); matrix.ScaleAppend(δy / δx, 1); XPoint pt1 = matrix.Transform(point1); XPoint pt2 = matrix.Transform(point2); // Get info about chord that connects both points. XPoint midPoint = new XPoint((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2); XVector vect = pt2 - pt1; double halfChord = vect.Length / 2; // Get vector from chord to center. XVector vectRotated; // (comparing two Booleans here!) if (isLargeArc == isCounterclockwise) vectRotated = new XVector(-vect.Y, vect.X); else vectRotated = new XVector(vect.Y, -vect.X); vectRotated.Normalize(); // Distance from chord to center. double centerDistance = Math.Sqrt(δy * δy - halfChord * halfChord); if (double.IsNaN(centerDistance)) centerDistance = 0; // Calculate center point. XPoint center = midPoint + centerDistance * vectRotated; // Get angles from center to the two points. double α = Math.Atan2(pt1.Y - center.Y, pt1.X - center.X); double β = Math.Atan2(pt2.Y - center.Y, pt2.X - center.X); // (another comparison of two Booleans!) if (isLargeArc == (Math.Abs(β - α) < Math.PI)) { if (α < β) α += 2 * Math.PI; else β += 2 * Math.PI; } // Invert matrix for final point calculation. matrix.Invert(); double sweepAngle = β - α; // Let the algorithm of GDI+ DrawArc to Bézier curves do the rest of the job return BezierCurveFromArc(center.X - δx * factor, center.Y - δy, 2 * δx * factor, 2 * δy, α / Calc.Deg2Rad, sweepAngle / Calc.Deg2Rad, pathStart, ref matrix); }
/// <summary> /// Some test code to check that there are no typing errors in the formulars. /// </summary> public static void Test() { XMatrix xm1 = new XMatrix(23, -35, 837, 332, -3, 12); Matrix m1 = new Matrix(23, -35, 837, 332, -3, 12); DumpMatrix(xm1, m1); XMatrix xm2 = new XMatrix(12, 235, 245, 42, 33, -56); Matrix m2 = xm2.ToMatrix(); DumpMatrix(xm2, m2); // xm1.Multiply(xm2, XMatrixOrder.Prepend); // m1.Multiply(m2, MatrixOrder.Append); xm1.Multiply(xm2, XMatrixOrder.Append); m1.Multiply(m2, MatrixOrder.Append); DumpMatrix(xm1, m1); xm1.Translate(-243, 342, XMatrixOrder.Append); m1.Translate(-243, 342, MatrixOrder.Append); DumpMatrix(xm1, m1); xm1.Scale(-5.66, 7.87); m1.Scale(-5.66f, 7.87f); // xm1.Scale(-5.66, 7.87, XMatrixOrder.Prepend); // m1.Scale(-5.66f, 7.87f, MatrixOrder.Prepend); DumpMatrix(xm1, m1); xm1.Rotate(135, XMatrixOrder.Append); m1.Rotate(135, MatrixOrder.Append); // xm1.Scale(-5.66, 7.87, XMatrixOrder.Prepend); // m1.Scale(-5.66f, 7.87f, MatrixOrder.Prepend); DumpMatrix(xm1, m1); xm1.RotateAt(177, new XPoint(-3456, 654), XMatrixOrder.Append); m1.RotateAt(177, new PointF(-3456, 654), MatrixOrder.Append); DumpMatrix(xm1, m1); xm1.Shear(0.76, -0.87, XMatrixOrder.Prepend); m1.Shear(0.76f, -0.87f, MatrixOrder.Prepend); DumpMatrix(xm1, m1); xm1 = new XMatrix(23, -35, 837, 332, -3, 12); m1 = new Matrix(23, -35, 837, 332, -3, 12); XPoint[] xpoints = new XPoint[3]{new XPoint(23, 10), new XPoint(-27, 120), new XPoint(-87, -55)}; PointF[] points = new PointF[3]{new PointF(23, 10), new PointF(-27, 120), new PointF(-87, -55)}; xm1.TransformPoints(xpoints); m1.TransformPoints(points); xm1.Invert(); m1.Invert(); DumpMatrix(xm1, m1); }