public static double AngleBetween(XVector vector1, XVector vector2) { double y = vector1.x * vector2.y - vector2.x * vector1.y; double x = vector1.x * vector2.x + vector1.y * vector2.y; return(Math.Atan2(y, x) * 57.295779513082323); }
public static bool Equals(XVector vector1, XVector vector2) { if (vector1.X.Equals(vector2.X)) { return(vector1.Y.Equals(vector2.Y)); } return(false); }
public static XVector Parse(string source) { TokenizerHelper helper = new TokenizerHelper(source, CultureInfo.InvariantCulture); string str = helper.NextTokenRequired(); XVector vector = new XVector(Convert.ToDouble(str, CultureInfo.InvariantCulture), Convert.ToDouble(helper.NextTokenRequired(), CultureInfo.InvariantCulture)); helper.LastTokenRequired(); return(vector); }
/// <summary> /// Moves a rectangle by the specified amount. /// </summary> public void Offset(XVector offsetVector) { if (IsEmpty) { throw new InvalidOperationException("CannotCallMethod"); //SR.Get(SRID.Rect_CannotCallMethod, new object[0])); } _x += offsetVector.X; _y += offsetVector.Y; }
public override bool Equals(object o) { if ((o == null) || !(o is XVector)) { return(false); } XVector vector = (XVector)o; return(Equals(this, vector)); }
public static double Multiply(XVector vector1, XVector vector2) { return(vector1._x * vector2._x + vector1._y * vector2._y); }
//+------------------------------------------------------------------------------------------------- // // Function: ArcToBezier // // Synopsis: Compute the Bezier approximation of an arc // // Notes: This utilitycomputes the Bezier approximation for an elliptical arc as it is defined // in the SVG arc spec. The ellipse from which the arc is carved is axis-aligned in its // own coordinates, and defined there by its x and y radii. The rotation angle defines // how the ellipse's axes are rotated relative to our x axis. The start and end points // define one of 4 possible arcs; the sweep and large-arc flags determine which one of // these arcs will be chosen. See SVG spec for details. // // Returning pieces = 0 indicates a line instead of an arc // pieces = -1 indicates that the arc degenerates to a point // //-------------------------------------------------------------------------------------------------- public static PointCollection ArcToBezier(double xStart, double yStart, double xRadius, double yRadius, double rotationAngle, bool isLargeArc, bool isClockwise, double xEnd, double yEnd, out int pieces) { double cosArcAngle, sinArcAngle, xCenter, yCenter, r, bezDist; XVector vecToBez1, vecToBez2; XMatrix matToEllipse; double fuzz2 = FUZZ * FUZZ; bool isZeroCenter = false; pieces = -1; // In the following, the line segment between between the arc's start and // end points is referred to as "the chord". // Transform 1: Shift the origin to the chord's midpoint double x = (xEnd - xStart) / 2; double y = (yEnd - yStart) / 2; double halfChord2 = x * x + y * y; // (half chord length)^2 // Degenerate case: single point if (halfChord2 < fuzz2) { // The chord degeneartes to a point, the arc will be ignored return null; } // Degenerate case: straight line if (!AcceptRadius(halfChord2, fuzz2, ref xRadius) || !AcceptRadius(halfChord2, fuzz2, ref yRadius)) { // We have a zero radius, add a straight line segment instead of an arc pieces = 0; return null; } if (xRadius == 0 || yRadius == 0) { // We have a zero radius, add a straight line segment instead of an arc pieces = 0; return null; } // Transform 2: Rotate to the ellipse's coordinate system rotationAngle = -rotationAngle * Calc.Deg2Rad; double cos = Math.Cos(rotationAngle); double sin = Math.Sin(rotationAngle); r = x * cos - y * sin; y = x * sin + y * cos; x = r; // Transform 3: Scale so that the ellipse will become a unit circle x /= xRadius; y /= yRadius; // We get to the center of that circle along a verctor perpendicular to the chord // from the origin, which is the chord's midpoint. By Pythagoras, the length of that // vector is sqrt(1 - (half chord)^2). halfChord2 = x * x + y * y; // now in the circle coordinates if (halfChord2 > 1) { // The chord is longer than the circle's diameter; we scale the radii uniformly so // that the chord will be a diameter. The center will then be the chord's midpoint, // which is now the origin. r = Math.Sqrt(halfChord2); xRadius *= r; yRadius *= r; xCenter = yCenter = 0; isZeroCenter = true; // Adjust the unit-circle coordinates x and y x /= r; y /= r; } else { // The length of (-y,x) or (x,-y) is sqrt(rHalfChord2), and we want a vector // of length sqrt(1 - rHalfChord2), so we'll multiply it by: r = Math.Sqrt((1 - halfChord2) / halfChord2); //if (isLargeArc != (eSweepDirection == SweepDirection.Clockwise)) if (isLargeArc != isClockwise) // Going to the center from the origin=chord-midpoint { // in the direction of (-y, x) xCenter = -r * y; yCenter = r * x; } else { // in the direction of (y, -x) xCenter = r * y; yCenter = -r * x; } } // Transformation 4: shift the origin to the center of the circle, which then becomes // the unit circle. Since the chord's midpoint is the origin, the start point is (-x, -y) // and the endpoint is (x, y). XPoint ptStart = new XPoint(-x - xCenter, -y - yCenter); XPoint ptEnd = new XPoint(x - xCenter, y - yCenter); // Set up the matrix that will take us back to our coordinate system. This matrix is // the inverse of the combination of transformation 1 thru 4. matToEllipse = new XMatrix(cos * xRadius, -sin * xRadius, sin * yRadius, cos * yRadius, (xEnd + xStart) / 2, (yEnd + yStart) / 2); if (!isZeroCenter) { // Prepend the translation that will take the origin to the circle's center matToEllipse.OffsetX += (matToEllipse.M11 * xCenter + matToEllipse.M21 * yCenter); matToEllipse.OffsetY += (matToEllipse.M12 * xCenter + matToEllipse.M22 * yCenter); } // Get the sine & cosine of the angle that will generate the arc pieces GetArcAngle(ptStart, ptEnd, isLargeArc, isClockwise, out cosArcAngle, out sinArcAngle, out pieces); // Get the vector to the first Bezier control point bezDist = GetBezierDistance(cosArcAngle, 1); //if (eSweepDirection == SweepDirection.Counterclockwise) if (!isClockwise) bezDist = -bezDist; vecToBez1 = new XVector(-bezDist * ptStart.Y, bezDist * ptStart.X); PointCollection result = new PointCollection(); // Add the arc pieces, except for the last for (int idx = 1; idx < pieces; idx++) { // Get the arc piece's endpoint XPoint ptPieceEnd = new XPoint(ptStart.X * cosArcAngle - ptStart.Y * sinArcAngle, ptStart.X * sinArcAngle + ptStart.Y * cosArcAngle); vecToBez2 = new XVector(-bezDist * ptPieceEnd.Y, bezDist * ptPieceEnd.X); result.Add(matToEllipse.Transform(ptStart + vecToBez1)); result.Add(matToEllipse.Transform(ptPieceEnd - vecToBez2)); result.Add(matToEllipse.Transform(ptPieceEnd)); // Move on to the next arc ptStart = ptPieceEnd; vecToBez1 = vecToBez2; } // Last arc - we know the endpoint vecToBez2 = new XVector(-bezDist * ptEnd.Y, bezDist * ptEnd.X); result.Add(matToEllipse.Transform(ptStart + vecToBez1)); result.Add(matToEllipse.Transform(ptEnd - vecToBez2)); result.Add(new XPoint(xEnd, yEnd)); return result; }
/// <summary> /// Subtracts a vector from a point. /// </summary> public static XPoint Subtract(XPoint point, XVector vector) { return new XPoint(point.x - vector.x, point.y - vector.y); }
public static XPoint Add(XVector vector, XPoint point) { return(new XPoint(point.X + vector._x, point.Y + vector._y)); }
/// <summary> /// Transforms the specified vectors by this matrix. /// </summary> public void Transform(XVector[] vectors) { if (vectors != null) { int count = vectors.Length; for (int idx = 0; idx < count; idx++) MultiplyVector(ref vectors[idx].x, ref vectors[idx].y); } }
public static XVector Subtract(XVector vector1, XVector vector2) { return(new XVector(vector1.x - vector2.x, vector1.y - vector2.y)); }
public static XVector Multiply(XVector vector, XMatrix matrix) { return(matrix.Transform(vector)); }
/// <summary> /// Initializes a new instance of the XRect class. /// </summary> public XRect(XPoint point, XVector vector) : this(point, point + vector) { }
/// <summary> /// Subtracts a vector from a point. /// </summary> public static XPoint Subtract(XPoint point, XVector vector) { return(new XPoint(point.x - vector.x, point.y - vector.y)); }
/// <summary> /// Moves a rectangle by the specified amount. /// </summary> public void Offset(XVector offsetVector) { if (IsEmpty) throw new InvalidOperationException("CannotCallMethod"); //SR.Get(SRID.Rect_CannotCallMethod, new object[0])); this.x += offsetVector.x; this.y += offsetVector.y; }
/// <summary> /// Returns a rectangle that is offset from the specified rectangle by using the specified vector. /// </summary> public static XRect Offset(XRect rect, XVector offsetVector) { rect.Offset(offsetVector.X, offsetVector.Y); return rect; }
/// <summary> /// Calculates the distance between an old anchor point and a new anchor point. /// </summary> /// <param name="oldType"></param> /// <param name="newType"></param> /// <param name="size"></param> public static XVector CalcDistance(AnchorType oldType, AnchorType newType, XSize size) { if (oldType == newType) return new XVector(); XVector result; Delta delta = CodeBase.deltas[(int)oldType, (int)newType]; result = new XVector(size.width / 2 * delta.x, size.height / 2 * delta.y); return result; }
public void DrawGraph(XGraphics gfx) { double yOff = page_.Height * 0.11; XRect rect = new XRect(20, yOff, page_.Width - 40, page_.Height - (yOff + 20)); DrawingUtil.DrawOutlineRect(rect, gfx, cornerRadius); gfx.DrawRoundedRectangle(backgroundBrush, rect, cornerRadius); XPoint center = new XPoint(page_.Width * 0.5, page_.Height * 0.45); //Left & right boxes XRect leftRect = new XRect(center.X - 250, yOff + 5, 160, 25); XRect rightRect = new XRect(center.X + 90, yOff + 5, 160, 25); DrawingUtil.DrawOutlineRect(leftRect, gfx, new XSize(10,10)); gfx.DrawRoundedRectangle(XBrushes.Yellow, leftRect, new XSize(10, 10)); DrawingUtil.DrawOutlineRect(rightRect, gfx, new XSize(10,10)); gfx.DrawRoundedRectangle(XBrushes.CornflowerBlue, rightRect, new XSize(10, 10)); gfx.DrawString("Left", new XFont("Arial", 20), XBrushes.Black, new XPoint(leftRect.X + 80, leftRect.Y + 15), XStringFormats.Center); gfx.DrawString("Right", new XFont("Arial", 20), XBrushes.Black, new XPoint(rightRect.X + 80, rightRect.Y + 15), XStringFormats.Center); float graphSize = (float)page_.Height * 0.175f; XPoint[] polyPoints = DrawingUtil.Instance.GeneratePoints(center, graphSize, 7, gfx); gfx.DrawPolygon(backgroundBrush, polyPoints, XFillMode.Winding); XPen yellowPen = new XPen(XColors.Yellow, 2.5); XPen greenPen = new XPen(XColors.Green, 2.5); XPen perimeterPen = XPens.LightGray; XPen redPen = new XPen(XColors.Red, 2.5); GraphIcon hipFlexImg = new GraphIcon(XImage.FromFile(Directory.GetCurrentDirectory() + @"\Content\HipFlex.png"),"Hip Flexion"); GraphIcon hamStringImg = new GraphIcon(XImage.FromFile(Directory.GetCurrentDirectory() + @"\Content\HSExt.png"), "Hamstring Extension"); GraphIcon hipAbdImg = new GraphIcon(XImage.FromFile(Directory.GetCurrentDirectory() + @"\Content\HipAbd.png"), "Hip Abduction"); GraphIcon hipIntImg = new GraphIcon(XImage.FromFile(Directory.GetCurrentDirectory() + @"\Content\HipInt.png"), "Hip Internal Rotation"); GraphIcon hipExtImg = new GraphIcon(XImage.FromFile(Directory.GetCurrentDirectory() + @"\Content\HipExt.png"), "Hip External Rotation"); GraphIcon kneeFlexImg = new GraphIcon(XImage.FromFile(Directory.GetCurrentDirectory() + @"\Content\KneeFlex.png"), "Knee Flexion"); GraphIcon AnkleFlexImg = new GraphIcon(XImage.FromFile(Directory.GetCurrentDirectory() + @"\Content\AnkleFlex.png"), "Ankle Flexion"); GraphIcon[] icons = new GraphIcon[] { hipFlexImg, hamStringImg, hipAbdImg, hipIntImg, hipExtImg, kneeFlexImg, AnkleFlexImg }; //center out for (int l = 0; l < polyPoints.Length - 1; l++) gfx.DrawLine(greenPen, center, polyPoints[l]); //percentage Lines & icons gfx.DrawString(0 + "%", new XFont("Arial", 10), XBrushes.Black, center + new XPoint(5, 0)); for (int j = 0; j < polyPoints.Length - 1; j++) { XPoint pt1 = polyPoints[j]; XPoint pt2 = polyPoints[j + 1]; for (int i = 10; i > 0; i--) { float increment = -i * 0.1f; if (j < 1) gfx.DrawString((i * 10).ToString() + '%', new XFont("Arial", 8), XBrushes.Black, DrawingUtil.Instance.Interpolate(center, polyPoints[0], increment) + new XPoint(5, 0)); gfx.DrawLine(perimeterPen, DrawingUtil.Instance.Interpolate(center, pt1, increment), DrawingUtil.Instance.Interpolate(center, pt2, increment)); } XVector vec = new XVector(pt1.X, pt1.Y); XVector vec2 = new XVector(center.X, center.Y); XImage img = icons[j].img; double wRatio = (double)img.PixelWidth / (double)img.PixelHeight; XVector dir = vec2 - vec; dir.Normalize(); double txtOffset = dir.X * -10; XPoint halfmg = new XPoint(-20, -20); XPoint imgpos = new XPoint(dir.X * (-graphSize - 50), dir.Y * (-graphSize - 50)) + center + halfmg; gfx.DrawImage(img, new XRect(imgpos, new XSize(wRatio * 60, 60))); gfx.DrawString(icons[j].txt, arialSmall, XBrushes.Black, imgpos + new XPoint(txtOffset, -10), XStringFormats.Center); } //leftSide XPoint[] percentagePoints = new XPoint[polyPoints.Length - 1]; for (int k = 0; k < polyPoints.Length - 1; k++) { Parameter kv = userParameters_.ElementAt(k); percentagePoints[k] = DrawingUtil.Instance.Interpolate(center, polyPoints[k], -kv.Percentage); gfx.DrawLine(yellowPen, center, DrawingUtil.Instance.Interpolate(center, polyPoints[k], -kv.AmberVal)); gfx.DrawLine(redPen, center, DrawingUtil.Instance.Interpolate(center, polyPoints[k], -kv.RedVal)); } gfx.DrawPolygon(new XPen(XColor.FromArgb(1, 0, 255, 255)), new XSolidBrush(XColor.FromArgb(100, 255, 255, 0)), percentagePoints, XFillMode.Alternate); XPoint[] linePoints = new XPoint[percentagePoints.Length + 1]; for (int i = 0; i < percentagePoints.Length; i++) { linePoints[i] = percentagePoints[i]; } linePoints[linePoints.Length - 1] = percentagePoints[0]; gfx.DrawLines(new XPen(XColor.FromArgb(255, 255, 255, 0), 2), linePoints); //right side for (int k = 10; k < polyPoints.Length + 9; k++) { Parameter kv = userParameters_.ElementAt(k); percentagePoints[k - 10] = DrawingUtil.Instance.Interpolate(center, polyPoints[k - 10], -kv.Percentage); gfx.DrawLine(yellowPen, center, DrawingUtil.Instance.Interpolate(center, polyPoints[k -10], -kv.AmberVal)); gfx.DrawLine(redPen, center, DrawingUtil.Instance.Interpolate(center, polyPoints[k - 10], -kv.RedVal)); } gfx.DrawPolygon(new XPen(XColor.FromArgb(1, 0, 255, 255)), new XSolidBrush(XColor.FromArgb(100, 54, 127, 180)), percentagePoints, XFillMode.Alternate); for (int i = 0; i < percentagePoints.Length; i++) { linePoints[i] = percentagePoints[i]; } linePoints[linePoints.Length - 1] = percentagePoints[0]; gfx.DrawLines(new XPen(XColor.FromArgb(255, 54, 127, 180), 2), linePoints); XRect leftRectLSI = new XRect(center.X - 250, page_.Height * 0.725, 120, 25); XRect rightRectLSI = new XRect(center.X + 70, page_.Height * 0.725, 120, 25); XRect LSIRect = new XRect(page_.Width - 100, page_.Height * 0.725, 35, 25); XSize rad = new XSize(10, 10); DrawingUtil.DrawOutlineRect(leftRectLSI, gfx, rad); DrawingUtil.DrawOutlineRect(rightRectLSI, gfx, rad); DrawingUtil.DrawOutlineRect(LSIRect, gfx, rad); gfx.DrawRoundedRectangle(XBrushes.Yellow, leftRectLSI,rad); gfx.DrawRoundedRectangle(XBrushes.CornflowerBlue, rightRectLSI, rad); gfx.DrawRoundedRectangle(XBrushes.LightGray, LSIRect, rad); gfx.DrawString("Left", new XFont("Arial", 14), XBrushes.Black, new XPoint(leftRectLSI.X + 60, leftRectLSI.Y + 12.5), XStringFormats.Center); gfx.DrawString("Right", new XFont("Arial", 14), XBrushes.Black, new XPoint(rightRectLSI.X + 60, rightRectLSI.Y + 12.5), XStringFormats.Center); gfx.DrawString("LSI", new XFont("Arial", 14), XBrushes.Black, new XPoint(LSIRect.X + 17.5, LSIRect.Y + 10), XStringFormats.Center); for (int l = 0; l < polyPoints.Length - 1; l++) { XBrush leftParamCol = XBrushes.Green; XBrush rightParamCol = XBrushes.Green; XBrush lsiParamCol = XBrushes.Green; XFont arial = new XFont("Arial", 13,XFontStyle.Bold); Parameter leftParam = userParameters_.ElementAt(l); Parameter rightParam = userParameters_.ElementAt(l + 10);; leftParamCol = DrawingUtil.Instance.ChooseBrushColor(leftParam.Color); rightParamCol = DrawingUtil.Instance.ChooseBrushColor(rightParam.Color); char degree = Convert.ToChar('\u00b0'); double increment = l * page_.Height * 0.025; double y = page_.Height * 0.775 + increment; XRect rl = new XRect(leftRectLSI.X + (leftRectLSI.Width * 0.5) - 25, y, 50, 15); DrawingUtil.DrawOutlineRect(rl, gfx, rad); gfx.DrawRoundedRectangle(leftParamCol, rl, rad); gfx.DrawString(leftParam.Value.ToString() + degree, arial, XBrushes.Black, new XPoint(rl.X + 25, rl.Y + 7.5), XStringFormats.Center); XRect rr = new XRect(rightRectLSI.X + (rightRectLSI.Width * 0.5) - 25, y, 50, 15); DrawingUtil.DrawOutlineRect(rr, gfx, rad); gfx.DrawRoundedRectangle(rightParamCol, rr, rad); gfx.DrawString(rightParam.Value.ToString() + degree, arial, XBrushes.Black, new XPoint(rr.X + 25, rr.Y + 7.5), XStringFormats.Center); XRect rlsi = new XRect(LSIRect.X + (LSIRect.Width * 0.5) - 17.5, y, 35, 15); DrawingUtil.DrawOutlineRect(rlsi, gfx, rad); lsiParamCol = DrawingUtil.Instance.ChooseBrushColor(leftParam.LSI, 49, 74); gfx.DrawRoundedRectangle(lsiParamCol, rlsi, rad); gfx.DrawString(leftParam.LSI.ToString("0") + "%", arial, XBrushes.Black, new XPoint(rlsi.X + 17.5, rlsi.Y + 7.5), XStringFormats.Center); gfx.DrawString(leftParam.Name.Substring(4,leftParam.Name.Length - 4), new XFont("Arial", 10), XBrushes.Black, DrawingUtil.Instance.Interpolate(new XPoint(rl.X + rl.Width, y + 7.5), new XPoint(rr.X, y), -0.5), XStringFormats.TopCenter); gfx.DrawLine(XPens.DarkSlateGray, new XPoint(leftRectLSI.X, rl.Y + 17.5), new XPoint(rlsi.X + 35, rl.Y + 17.5)); } }
public static double Determinant(XVector vector1, XVector vector2) { return(vector1._x * vector2._y - vector1._y * vector2._x); }
//+------------------------------------------------------------------------------------------------- // // Function: ArcToBezier // // Synopsis: Compute the Bezier approximation of an arc // // Notes: This utilitycomputes the Bezier approximation for an elliptical arc as it is defined // in the SVG arc spec. The ellipse from which the arc is carved is axis-aligned in its // own coordinates, and defined there by its x and y radii. The rotation angle defines // how the ellipse's axes are rotated relative to our x axis. The start and end points // define one of 4 possible arcs; the sweep and large-arc flags determine which one of // these arcs will be chosen. See SVG spec for details. // // Returning pieces = 0 indicates a line instead of an arc // pieces = -1 indicates that the arc degenerates to a point // //-------------------------------------------------------------------------------------------------- public static PointCollection ArcToBezier(double xStart, double yStart, double xRadius, double yRadius, double rotationAngle, bool isLargeArc, bool isClockwise, double xEnd, double yEnd, out int pieces) { double cosArcAngle, sinArcAngle, xCenter, yCenter, r, bezDist; XVector vecToBez1, vecToBez2; XMatrix matToEllipse; double fuzz2 = FUZZ * FUZZ; bool isZeroCenter = false; pieces = -1; // In the following, the line segment between between the arc's start and // end points is referred to as "the chord". // Transform 1: Shift the origin to the chord's midpoint double x = (xEnd - xStart) / 2; double y = (yEnd - yStart) / 2; double halfChord2 = x * x + y * y; // (half chord length)^2 // Degenerate case: single point if (halfChord2 < fuzz2) { // The chord degeneartes to a point, the arc will be ignored return(null); } // Degenerate case: straight line if (!AcceptRadius(halfChord2, fuzz2, ref xRadius) || !AcceptRadius(halfChord2, fuzz2, ref yRadius)) { // We have a zero radius, add a straight line segment instead of an arc pieces = 0; return(null); } if (xRadius == 0 || yRadius == 0) { // We have a zero radius, add a straight line segment instead of an arc pieces = 0; return(null); } // Transform 2: Rotate to the ellipse's coordinate system rotationAngle = -rotationAngle * Calc.Deg2Rad; double cos = Math.Cos(rotationAngle); double sin = Math.Sin(rotationAngle); r = x * cos - y * sin; y = x * sin + y * cos; x = r; // Transform 3: Scale so that the ellipse will become a unit circle x /= xRadius; y /= yRadius; // We get to the center of that circle along a verctor perpendicular to the chord // from the origin, which is the chord's midpoint. By Pythagoras, the length of that // vector is sqrt(1 - (half chord)^2). halfChord2 = x * x + y * y; // now in the circle coordinates if (halfChord2 > 1) { // The chord is longer than the circle's diameter; we scale the radii uniformly so // that the chord will be a diameter. The center will then be the chord's midpoint, // which is now the origin. r = Math.Sqrt(halfChord2); xRadius *= r; yRadius *= r; xCenter = yCenter = 0; isZeroCenter = true; // Adjust the unit-circle coordinates x and y x /= r; y /= r; } else { // The length of (-y,x) or (x,-y) is sqrt(rHalfChord2), and we want a vector // of length sqrt(1 - rHalfChord2), so we'll multiply it by: r = Math.Sqrt((1 - halfChord2) / halfChord2); //if (isLargeArc != (eSweepDirection == SweepDirection.Clockwise)) if (isLargeArc != isClockwise) // Going to the center from the origin=chord-midpoint { // in the direction of (-y, x) xCenter = -r * y; yCenter = r * x; } else { // in the direction of (y, -x) xCenter = r * y; yCenter = -r * x; } } // Transformation 4: shift the origin to the center of the circle, which then becomes // the unit circle. Since the chord's midpoint is the origin, the start point is (-x, -y) // and the endpoint is (x, y). XPoint ptStart = new XPoint(-x - xCenter, -y - yCenter); XPoint ptEnd = new XPoint(x - xCenter, y - yCenter); // Set up the matrix that will take us back to our coordinate system. This matrix is // the inverse of the combination of transformation 1 thru 4. matToEllipse = new XMatrix(cos * xRadius, -sin * xRadius, sin * yRadius, cos * yRadius, (xEnd + xStart) / 2, (yEnd + yStart) / 2); if (!isZeroCenter) { // Prepend the translation that will take the origin to the circle's center matToEllipse.OffsetX += (matToEllipse.M11 * xCenter + matToEllipse.M21 * yCenter); matToEllipse.OffsetY += (matToEllipse.M12 * xCenter + matToEllipse.M22 * yCenter); } // Get the sine & cosine of the angle that will generate the arc pieces GetArcAngle(ptStart, ptEnd, isLargeArc, isClockwise, out cosArcAngle, out sinArcAngle, out pieces); // Get the vector to the first Bezier control point bezDist = GetBezierDistance(cosArcAngle, 1); //if (eSweepDirection == SweepDirection.Counterclockwise) if (!isClockwise) { bezDist = -bezDist; } vecToBez1 = new XVector(-bezDist * ptStart.Y, bezDist * ptStart.X); PointCollection result = new PointCollection(); // Add the arc pieces, except for the last for (int idx = 1; idx < pieces; idx++) { // Get the arc piece's endpoint XPoint ptPieceEnd = new XPoint(ptStart.X * cosArcAngle - ptStart.Y * sinArcAngle, ptStart.X * sinArcAngle + ptStart.Y * cosArcAngle); vecToBez2 = new XVector(-bezDist * ptPieceEnd.Y, bezDist * ptPieceEnd.X); result.Add(matToEllipse.Transform(ptStart + vecToBez1)); result.Add(matToEllipse.Transform(ptPieceEnd - vecToBez2)); result.Add(matToEllipse.Transform(ptPieceEnd)); // Move on to the next arc ptStart = ptPieceEnd; vecToBez1 = vecToBez2; } // Last arc - we know the endpoint vecToBez2 = new XVector(-bezDist * ptEnd.Y, bezDist * ptEnd.X); result.Add(matToEllipse.Transform(ptStart + vecToBez1)); result.Add(matToEllipse.Transform(ptEnd - vecToBez2)); result.Add(new XPoint(xEnd, yEnd)); return(result); }
public static bool Equals(XVector vector1, XVector vector2) { return vector1.x == vector2.x && vector1.y == vector2.y; }
public static XVector Add(XVector vector1, XVector vector2) { return(new XVector(vector1._x + vector2._x, vector1._y + vector2._y)); }
/// <summary> /// Adds a point and a vector. /// </summary> public static XPoint Add(XPoint point, XVector vector) { return(new XPoint(point._x + vector.X, point._y + vector.Y)); }
public static XVector Multiply(double scalar, XVector vector) { return(new XVector(vector.x * scalar, vector.y * scalar)); }
/// <summary> /// Subtracts a vector from a point. /// </summary> public static XPoint Subtract(XPoint point, XVector vector) { return(new XPoint(point._x - vector.X, point._y - vector.Y)); }
public static double Determinant(XVector vector1, XVector vector2) { return(vector1.x * vector2.y - vector1.y * vector2.x); }
public static double CrossProduct(XVector vector1, XVector vector2) { return vector1.x * vector2.y - vector1.y * vector2.x; }
/// <summary> /// Transforms the specified vector by this Matrix and returns the result. /// </summary> public XVector Transform(XVector vector) { XVector vector2 = vector; MultiplyVector(ref vector2.x, ref vector2.y); return vector2; }
public static double AngleBetween(XVector vector1, XVector vector2) { double y = vector1.x * vector2.y - vector2.x * vector1.y; double x = vector1.x * vector2.x + vector1.y * vector2.y; return (Math.Atan2(y, x) * 57.295779513082323); }
/// <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> /// Returns a rectangle that is offset from the specified rectangle by using the specified vector. /// </summary> public static XRect Offset(XRect rect, XVector offsetVector) { rect.Offset(offsetVector.X, offsetVector.Y); return(rect); }
/// <summary> /// Adds a point and a vector. /// </summary> public static XPoint Add(XPoint point, XVector vector) { return new XPoint(point.x + vector.x, point.y + vector.y); }
public static XVector Add(XVector vector1, XVector vector2) { return new XVector(vector1.x + vector2.x, vector1.y + vector2.y); }
public static XVector Multiply(XVector vector, double scalar) { return(new XVector(vector._x * scalar, vector._y * scalar)); }
/// <summary> /// Indicates whether the values are so close that they can be considered as equal. /// </summary> public static bool AreClose(XVector vector1, XVector vector2) { return AreClose(vector1.X, vector2.X) && AreClose(vector1.Y, vector2.Y); }
public static XVector Subtract(XVector vector1, XVector vector2) { return new XVector(vector1.x - vector2.x, vector1.y - vector2.y); }
/// <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)); }
public static XVector Multiply(double scalar, XVector vector) { return new XVector(vector.x * scalar, vector.y * scalar); }
public static double CrossProduct(XVector vector1, XVector vector2) { return(vector1.x * vector2.y - vector1.y * vector2.x); }
public static XVector Divide(XVector vector, double scalar) { return vector * (1.0 / scalar); }
public static XVector Add(XVector vector1, XVector vector2) { return(new XVector(vector1.x + vector2.x, vector1.y + vector2.y)); }
public static XVector Multiply(XVector vector, XMatrix matrix) { return matrix.Transform(vector); }
public static XPoint Add(XVector vector, XPoint point) { return(new XPoint(point.x + vector.x, point.y + vector.y)); }
public static double Multiply(XVector vector1, XVector vector2) { return vector1.x * vector2.x + vector1.y * vector2.y; }
public static XVector Divide(XVector vector, double scalar) { return(vector * (1.0 / scalar)); }
public static double CrossProduct(XVector vector1, XVector vector2) { return(vector1._x * vector2._y - vector1._y * vector2._x); }
public static double Multiply(XVector vector1, XVector vector2) { return(vector1.x * vector2.x + vector1.y * vector2.y); }
public bool Equals(XVector value) { return Equals(this, value); }
public static double Determinant(XVector vector1, XVector vector2) { return vector1.x * vector2.y - vector1.y * vector2.x; }
public static XVector Subtract(XVector vector1, XVector vector2) { return(new XVector(vector1._x - vector2._x, vector1._y - vector2._y)); }
public bool Equals(XVector value) { return(Equals(this, value)); }
public static bool Equals(XVector vector1, XVector vector2) { if (vector1.X.Equals(vector2.X)) return vector1.Y.Equals(vector2.Y); return false; }