/// <summary> /// Calculates the distance between two points. /// </summary> /// <param name="p1">First point.</param> /// <param name="p2">Second point.</param> /// <returns>The distance between points p1 and p2.</returns> public static double Distance(PointD2D p1, PointD2D p2) { double x = p1.X - p2.X; double y = p1.Y - p2.Y; return(Math.Sqrt(x * x + y * y)); }
/// <summary> /// Handles the drawing of a straight single line. /// </summary> /// <param name="position">Mouse position.</param> /// <param name="e">EventArgs.</param> /// <returns>The mouse state handler for handling the next mouse events.</returns> public override void OnClick(PointD2D position, MouseButtonEventArgs e) { base.OnClick(position, e); if (0 == _currentPoint) { _cachedActiveLayer = _grac.ActiveLayer; _cachedActiveLayerTransformation = _cachedActiveLayer.TransformationFromRootToHere(); _cachedActiveLayerTransformationGdi = (Matrix)_cachedActiveLayerTransformation; } // get the page coordinates (in Point (1/72") units) var rootLayerCoord = _positionCurrentMouseInRootLayerCoordinates; // with knowledge of the current active layer, calculate the layer coordinates from them var layerCoord = _cachedActiveLayerTransformation.InverseTransformPoint(rootLayerCoord); _Points[_currentPoint].LayerCoordinates = layerCoord; _Points[_currentPoint].RootLayerCoordinates = rootLayerCoord; _currentPoint++; if (2 == _currentPoint) { FinishDrawing(); _currentPoint = 0; _grac.SetGraphToolFromInternal(NextMouseHandlerType); } }
/// <summary> /// Handles the drawing of a straight single line. /// </summary> /// <param name="position">Mouse position.</param> /// <param name="e">EventArgs.</param> /// <returns>The mouse state handler for handling the next mouse events.</returns> public override void OnClick(PointD2D position, MouseButtonEventArgs e) { base.OnClick(position, e); if (0 == _currentPoint) { _cachedActiveLayer = _grac.ActiveLayer; _cachedActiveLayerTransformation = _cachedActiveLayer.TransformationFromRootToHere(); _cachedActiveLayerTransformationGdi = (Matrix)_cachedActiveLayerTransformation; } // get the page coordinates (in Point (1/72") units) var rootLayerCoord = _positionCurrentMouseInRootLayerCoordinates; // with knowledge of the current active layer, calculate the layer coordinates from them var layerCoord = _cachedActiveLayerTransformation.InverseTransformPoint(rootLayerCoord); if (e.ChangedButton == MouseButton.Right) { FinishDrawing(); } else { _Points.Add(new POINT() { LayerCoordinates = layerCoord, RootLayerCoordinates = rootLayerCoord }); _currentPoint++; } }
/// <summary> /// Calculates the squared distance between a finite line and a point. /// </summary> /// <param name="point">The location of the point.</param> /// <param name="lineOrg">The location of the line origin.</param> /// <param name="lineEnd">The location of the line end.</param> /// <returns>The squared distance between the line (threated as having a finite length) and the point.</returns> public static double SquareDistanceLineToPoint(PointD2D point, PointD2D lineOrg, PointD2D lineEnd) { var linex = lineEnd.X - lineOrg.X; var liney = lineEnd.Y - lineOrg.Y; var pointx = point.X - lineOrg.X; var pointy = point.Y - lineOrg.Y; var rsquare = linex * linex + liney * liney; var xx = linex * pointx + liney * pointy; if (xx <= 0) // the point is located before the line, so use { // the distance of the line origin to the point return(pointx * pointx + pointy * pointy); } else if (xx >= rsquare) // the point is located after the line, so use { // the distance of the line end to the point pointx = point.X - lineEnd.X; pointy = point.Y - lineEnd.Y; return(pointx * pointx + pointy * pointy); } else // the point is located in the middle of the line, use the { // distance from the line to the point var yy = liney * pointx - linex * pointy; return(yy * yy / rsquare); } }
/// <summary> /// Expands this rectangle, so that it contains the point p. /// </summary> /// <param name="p">The point that should be contained in this rectangle.</param> /// <returns>The new rectangle that now contains the point p.</returns> public void ExpandToInclude(PointD2D p) { if (!(Contains(p))) { if (p.X < X) { Width += X - p.X; X = p.X; } else if (p.X > Right) { Width = p.X - X; } if (p.Y < Y) { Height += Y - p.Y; Y = p.Y; } else if (p.Y > Bottom) { Height = p.Y - Y; } } }
public EmbeddedImageGraphic(PointD2D graphicPosition, ImageProxy startingImage) : this() { this.SetPosition(graphicPosition, Main.EventFiring.Suppressed); this.Image = startingImage; }
/// <summary> /// Converts an open cardinal spline, given by the points in <paramref name="points"/>, to Bezier segments. /// </summary> /// <param name="points">The control points of the open cardinal spline curve.</param> /// <param name="count">Number of control points of the closed cardinal spline curve.</param> /// <param name="tension">The tension of the cardinal spline.</param> /// <returns>Bezier segments that constitute the closed curve.</returns> /// <remarks>Original name in Wine source: GdipAddPathClosedCurve2</remarks> public static PointD2D[] OpenCardinalSplineToBezierSegments(PointD2D[] points, int count, double tension) { const double TENSION_CONST = 0.3; int len_pt = count * 3 - 2; var pt = new PointD2D[len_pt]; tension = tension * TENSION_CONST; var p1 = Calc_Curve_Bezier_Endpoint(points[0], points[1], tension); pt[0] = points[0]; pt[1] = p1; var p2 = p1; for (int i = 0; i < count - 2; i++) { Calc_Curve_Bezier(points, i, tension, out p1, out p2); pt[3 * i + 2] = p1; pt[3 * i + 3] = points[i + 1]; pt[3 * i + 4] = p2; } p1 = Calc_Curve_Bezier_Endpoint(points[count - 1], points[count - 2], tension); pt[len_pt - 2] = p1; pt[len_pt - 1] = points[count - 1]; return pt; }
public bool FlattenBezierSegment(int recursionLevel, PointD2D p0_0, PointD2D p1_0, PointD2D p2_0, PointD2D p3_0, List<PointD2D> flattenedList, int insertIdx) { if (!IsBezierSegmentFlatEnough(p0_0, p1_0, p2_0, p3_0)) { var p0_1 = new PointD2D(0.5 * (p0_0.X + p1_0.X), 0.5 * (p0_0.Y + p1_0.Y)); var p1_1 = new PointD2D(0.5 * (p1_0.X + p2_0.X), 0.5 * (p1_0.Y + p2_0.Y)); var p2_1 = new PointD2D(0.5 * (p2_0.X + p3_0.X), 0.5 * (p2_0.Y + p3_0.Y)); var p0_2 = new PointD2D(0.5 * (p0_1.X + p1_1.X), 0.5 * (p0_1.Y + p1_1.Y)); var p1_2 = new PointD2D(0.5 * (p1_1.X + p2_1.X), 0.5 * (p1_1.Y + p2_1.Y)); var p0_3 = new PointD2D(0.5 * (p0_2.X + p1_2.X), 0.5 * (p0_2.Y + p1_2.Y)); flattenedList.Insert(insertIdx, p0_3); if (recursionLevel < 24) { // now flatten the right side first FlattenBezierSegment(recursionLevel + 1, p0_3, p1_2, p2_1, p3_0, flattenedList, insertIdx + 1); // and the left side FlattenBezierSegment(recursionLevel + 1, p0_0, p0_1, p0_2, p0_3, flattenedList, insertIdx); } return true; } return false; }
/// <summary> /// Sets the selected pivot values for X and Y. Additionally, the reference size is required. /// </summary> /// <param name="pivotX">The pivot x value.</param> /// <param name="pivotY">The pivot y value.</param> /// <param name="referenceSize">Size of the reference area.</param> public void SetSelectedPivot(RADouble pivotX, RADouble pivotY, PointD2D referenceSize) { _pivotX = pivotX; _pivotY = pivotY; _percentLayerXSizeUnit.ReferenceQuantity = new DimensionfulQuantity(referenceSize.X, Units.Length.Point.Instance); _percentLayerYSizeUnit.ReferenceQuantity = new DimensionfulQuantity(referenceSize.Y, Units.Length.Point.Instance); _xSizeEnvironment = new QuantityWithUnitGuiEnvironment(GuiLengthUnits.Collection, _percentLayerXSizeUnit); _ySizeEnvironment = new QuantityWithUnitGuiEnvironment(GuiLengthUnits.Collection, _percentLayerYSizeUnit); _guiPivotX.UnitEnvironment = _xSizeEnvironment; _guiPivotY.UnitEnvironment = _ySizeEnvironment; _guiPivotX.SelectedQuantity = _pivotX.IsAbsolute ? new Units.DimensionfulQuantity(_pivotX.Value, Units.Length.Point.Instance) : new Units.DimensionfulQuantity(_pivotX.Value * 100, _percentLayerXSizeUnit); _guiPivotY.SelectedQuantity = _pivotY.IsAbsolute ? new Units.DimensionfulQuantity(_pivotY.Value, Units.Length.Point.Instance) : new Units.DimensionfulQuantity(_pivotY.Value * 100, _percentLayerYSizeUnit); if (CanUseRadioGridView()) { SetRadioButton(); SetUseOfRadioGrid(true); } else { SetUseOfRadioGrid(false); } SetVisibilityOfSwitchButton(); }
public void MoveGrip(PointD2D newPosition) { newPosition = _parent.Transformation.InverseTransformPoint(newPosition); var diff = new PointD2D(newPosition.X - _fixaPosition.X, newPosition.Y - _fixaPosition.Y); GraphObject.SetRotationFrom(_fixrPosition, _fixaPosition, _drawrPosition, diff, Main.EventFiring.Suppressed); _hasMoved = true; }
/// <summary> /// Calculates the squared distance between a finite line and a point. /// </summary> /// <param name="point">The location of the point.</param> /// <param name="lineOrg">The location of the line origin.</param> /// <param name="lineEnd">The location of the line end.</param> /// <returns>The squared distance between the line (threated as having a finite length) and the point.</returns> public static double SquareDistanceLineToPoint(PointD2D point, PointD2D lineOrg, PointD2D lineEnd) { var linex = lineEnd.X - lineOrg.X; var liney = lineEnd.Y - lineOrg.Y; var pointx = point.X - lineOrg.X; var pointy = point.Y - lineOrg.Y; var rsquare = linex * linex + liney * liney; var xx = linex * pointx + liney * pointy; if (xx <= 0) // the point is located before the line, so use { // the distance of the line origin to the point return pointx * pointx + pointy * pointy; } else if (xx >= rsquare) // the point is located after the line, so use { // the distance of the line end to the point pointx = point.X - lineEnd.X; pointy = point.Y - lineEnd.Y; return pointx * pointx + pointy * pointy; } else // the point is located in the middle of the line, use the { // distance from the line to the point var yy = liney * pointx - linex * pointy; return yy * yy / rsquare; } }
/// <summary> /// Activates this grip, providing the initial position of the mouse. /// </summary> /// <param name="initialPosition">Initial position of the mouse.</param> /// <param name="isActivatedUponCreation">If true the activation is called right after creation of this handle. If false, /// thie activation is due to a regular mouse click in this grip.</param> public void Activate(PointD2D initialPosition, bool isActivatedUponCreation) { _wasActivatedUponCreation = isActivatedUponCreation; _initialMousePosition = initialPosition; _initialObjectPosition = ((GraphicBase)_parent.HittedObject).Position; _hasMoved = false; }
/// <summary> /// Calculates the squared distance between two points. /// </summary> /// <param name="p1">First point.</param> /// <param name="p2">Second point.</param> /// <returns>The distance between points p1 and p2.</returns> public static double DistanceSquared(PointD2D p1, PointD2D p2) { var x = p1.X - p2.X; var y = p1.Y - p2.Y; return(x * x + y * y); }
public LinkedImageGraphic(PointD2D graphicPosition, string ImagePath) : this() { this.SetPosition(graphicPosition, Main.EventFiring.Suppressed); this.ImagePath = ImagePath; }
public RectangleD2D(PointD2D position, PointD2D size) { _x = position.X; _y = position.Y; _w = size.X; _h = size.Y; }
// see also source of wine at: http://source.winehq.org/source/dlls/gdiplus/graphicspath.c#L445 // /// <summary> /// Calculates Bezier points from cardinal spline endpoints. /// </summary> /// <param name="end">The end point.</param> /// <param name="adj">The adjacent point next to the endpoint.</param> /// <param name="tension">The tension.</param> /// <returns></returns> /// <remarks>Original name in Wine sources: calc_curve_bezier_endp</remarks> private static PointD2D Calc_Curve_Bezier_Endpoint(PointD2D end, PointD2D adj, double tension) { // tangent at endpoints is the line from the endpoint to the adjacent point return(new PointD2D( (tension * (adj.X - end.X) + end.X), (tension * (adj.Y - end.Y) + end.Y))); }
/// <summary> /// Converts a closed cardinal spline, given by the points in <paramref name="points"/>, to Bezier segments. /// </summary> /// <param name="points">The control points of the closed cardinal spline curve.</param> /// <param name="count">Number of control points of the closed cardinal spline curve.</param> /// <param name="tension">The tension of the cardinal spline.</param> /// <returns>Bezier segments that constitute the closed curve.</returns> /// <remarks>Original name in Wine source: GdipAddPathClosedCurve2</remarks> public static PointD2D[] ClosedCardinalSplineToBezierSegments(PointD2D[] points, int count, double tension) { const double TENSION_CONST = 0.3; var len_pt = (count + 1) * 3 - 2; var pt = new PointD2D[len_pt]; tension = tension * TENSION_CONST; PointD2D p1, p2; for (int i = 0; i < count - 2; i++) { Calc_Curve_Bezier(points, i, tension, out p1, out p2); pt[3 * i + 2] = p1; pt[3 * i + 3] = points[i + 1]; pt[3 * i + 4] = p2; } // calculation around last point of the original curve Calc_Curve_Bezier(points[count - 2], points[count - 1], points[0], tension, out p1, out p2); pt[len_pt - 5] = p1; pt[len_pt - 4] = points[count - 1]; pt[len_pt - 3] = p2; // calculation around first point of the original curve Calc_Curve_Bezier(points[count - 1], points[0], points[1], tension, out p1, out p2); pt[len_pt - 2] = p1; pt[len_pt - 1] = points[0]; // close path pt[0] = points[0]; pt[1] = p2; return(pt); }
/// <summary> /// Converts an open cardinal spline, given by the points in <paramref name="points"/>, to Bezier segments. /// </summary> /// <param name="points">The control points of the open cardinal spline curve.</param> /// <param name="count">Number of control points of the closed cardinal spline curve.</param> /// <param name="tension">The tension of the cardinal spline.</param> /// <returns>Bezier segments that constitute the closed curve.</returns> /// <remarks>Original name in Wine source: GdipAddPathClosedCurve2</remarks> public static PointD2D[] OpenCardinalSplineToBezierSegments(PointD2D[] points, int count, double tension) { const double TENSION_CONST = 0.3; int len_pt = count * 3 - 2; var pt = new PointD2D[len_pt]; tension = tension * TENSION_CONST; var p1 = Calc_Curve_Bezier_Endpoint(points[0], points[1], tension); pt[0] = points[0]; pt[1] = p1; var p2 = p1; for (int i = 0; i < count - 2; i++) { Calc_Curve_Bezier(points, i, tension, out p1, out p2); pt[3 * i + 2] = p1; pt[3 * i + 3] = points[i + 1]; pt[3 * i + 4] = p2; } p1 = Calc_Curve_Bezier_Endpoint(points[count - 1], points[count - 2], tension); pt[len_pt - 2] = p1; pt[len_pt - 1] = points[count - 1]; return(pt); }
// see also source of wine at: http://source.winehq.org/source/dlls/gdiplus/graphicspath.c#L445 // /// <summary> /// Calculates Bezier points from cardinal spline endpoints. /// </summary> /// <param name="end">The end point.</param> /// <param name="adj">The adjacent point next to the endpoint.</param> /// <param name="tension">The tension.</param> /// <returns></returns> /// <remarks>Original name in Wine sources: calc_curve_bezier_endp</remarks> static PointD2D Calc_Curve_Bezier_Endpoint(PointD2D end, PointD2D adj, double tension) { // tangent at endpoints is the line from the endpoint to the adjacent point return new PointD2D( (tension * (adj.X - end.X) + end.X), (tension * (adj.Y - end.Y) + end.Y)); }
/// <summary> /// Initializes a new instance of the <see cref="ResizeGripHandle"/> class. /// </summary> /// <param name="parent">The data for the object that is about to be resized.</param> /// <param name="relPos">The relative position of the handle. A value of 0 designates left (x) or top (y). A value of 1 designates right (x) or bottom (y).</param> /// <param name="spanningHalfYRhombus">The spanning half y rhombus.</param> public ResizeGripHandle(IHitTestObject parent, PointD2D relPos, MatrixD2D spanningHalfYRhombus) { _parent = parent; _drawrPosition = relPos; _fixrPosition = new PointD2D(relPos.X == 0 ? 1 : 0, relPos.Y == 0 ? 1 : 0); _fixaPosition = GraphObject.RelativeLocalToAbsoluteParentCoordinates(_fixrPosition); _spanningHalfYRhombus = spanningHalfYRhombus; }
public ShearGripHandle(IHitTestObject parent, PointD2D relPos, MatrixD2D spanningHalfYRhombus) { _parent = parent; _drawrPosition = relPos; _fixrPosition = new PointD2D(relPos.X == 0 ? 1 : 0, relPos.Y == 0 ? 1 : 0); _fixaPosition = GraphObject.RelativeToAbsolutePosition(_fixrPosition, true); _spanningHalfYRhombus = spanningHalfYRhombus; }
public void MoveGrip(PointD2D newPosition) { newPosition = _parent.Transformation.InverseTransformPoint(newPosition); PointD2D diff = new PointD2D(newPosition.X - _initialMousePosition.X, newPosition.Y - _initialMousePosition.Y); GraphObject.SetShearFrom(_fixrPosition, _fixaPosition, _drawrPosition, diff, _initialRotation, _initialShear, _initialScaleX, _initialScaleY, Main.EventFiring.Suppressed); _hasMoved = true; }
/// <summary> /// Calculates the control points of the incoming and outgoing Bezier segment around the original point at index i+1. /// </summary> /// <param name="pts">The original points thought to be connected by a cardinal spline.</param> /// <param name="i">The index i. To calculate the control points, the indices i, i+1 and i+2 are used from the point array <paramref name="pts"/>.</param> /// <param name="tension">The tension of the cardinal spline.</param> /// <param name="p1">The Bezier control point that controls the slope towards the point <paramref name="pts"/>[i+1].</param> /// <param name="p2">The Bezier control point that controls the slope outwards from the point <paramref name="pts"/>[i+1].</param> /// <remarks>Original name in Wine source: calc_curve_bezier</remarks> private static void Calc_Curve_Bezier(PointD2D[] pts, int i, double tension, out PointD2D p1, out PointD2D p2) { /* calculate tangent */ var diff = pts[2 + i] - pts[i]; /* apply tangent to get control points */ p1 = pts[1 + i] - tension * diff; p2 = pts[1 + i] + tension * diff; }
/// <summary> /// Calculates the control points of the incoming and outgoing Bezier segment around the original point at index i+1. /// </summary> /// <param name="pts">The original points thought to be connected by a cardinal spline.</param> /// <param name="i">The index i. To calculate the control points, the indices i, i+1 and i+2 are used from the point array <paramref name="pts"/>.</param> /// <param name="tension">The tension of the cardinal spline.</param> /// <param name="p1">The Bezier control point that controls the slope towards the point <paramref name="pts"/>[i+1].</param> /// <param name="p2">The Bezier control point that controls the slope outwards from the point <paramref name="pts"/>[i+1].</param> /// <remarks>Original name in Wine source: calc_curve_bezier</remarks> static void Calc_Curve_Bezier(PointD2D[] pts, int i, double tension, out PointD2D p1, out PointD2D p2) { /* calculate tangent */ var diff = pts[2 + i] - pts[i]; /* apply tangent to get control points */ p1 = pts[1 + i] - tension * diff; p2 = pts[1 + i] + tension * diff; }
/// <summary> /// Calculates the control points of the incoming and outgoing Bezier segment around the original point <paramref name="p1"/>. /// </summary> /// <param name="pts0">The previous point on a cardinal spline curce.</param> /// <param name="pts1">The point on a cardinal spline curve for which to calculate the incoming and outgoing Bezier control points.</param> /// <param name="pts2">The nex point on the cardinal spline curve.</param> /// <param name="tension">The tension of the cardinal spline.</param> /// <param name="p1">The Bezier control point that controls the slope towards the point <paramref name="pts1"/>.</param> /// <param name="p2">The Bezier control point that controls the slope outwards from the point <paramref name="pts1"/>.</param> /// <remarks>This function is not in the original Wine sources. It is introduced here for optimization to avoid allocation of a new array when converting closed cardinal spline curves.</remarks> private static void Calc_Curve_Bezier(PointD2D pts0, PointD2D pts1, PointD2D pts2, double tension, out PointD2D p1, out PointD2D p2) { /* calculate tangent */ var diff = pts2 - pts0; /* apply tangent to get control points */ p1 = pts1 - tension * diff; p2 = pts1 + tension * diff; }
/// <summary> /// Calculates the control points of the incoming and outgoing Bezier segment around the original point <paramref name="p1"/>. /// </summary> /// <param name="pts0">The previous point on a cardinal spline curce.</param> /// <param name="pts1">The point on a cardinal spline curve for which to calculate the incoming and outgoing Bezier control points.</param> /// <param name="pts2">The nex point on the cardinal spline curve.</param> /// <param name="tension">The tension of the cardinal spline.</param> /// <param name="p1">The Bezier control point that controls the slope towards the point <paramref name="pts1"/>.</param> /// <param name="p2">The Bezier control point that controls the slope outwards from the point <paramref name="pts1"/>.</param> /// <remarks>This function is not in the original Wine sources. It is introduced here for optimization to avoid allocation of a new array when converting closed cardinal spline curves.</remarks> static void Calc_Curve_Bezier(PointD2D pts0, PointD2D pts1, PointD2D pts2, double tension, out PointD2D p1, out PointD2D p2) { /* calculate tangent */ var diff = pts2 - pts0; /* apply tangent to get control points */ p1 = pts1 - tension * diff; p2 = pts1 + tension * diff; }
public bool IsAngleBelowCriterium(PointD2D v1, PointD2D v2) { double r = v1.X * v2.X + v1.Y * v2.Y; if (r <= 0) return false; r = r * r / ((v1.X * v1.X + v1.Y * v1.Y) * (v2.X * v2.X + v2.Y * v2.Y)); return r > _angleCriterium; // 1 Degree }
public void MoveGrip(PointD2D newPosition) { newPosition = _parent.Transformation.InverseTransformPoint(newPosition); var diff = GraphObject.ToUnrotatedDifference(_fixaPosition, newPosition); diff -= _initialMousePosition; GraphObject.SetScalesFrom(_fixrPosition, _fixaPosition, _drawrPosition, diff, _initialScaleX, _initialScaleY, Main.EventFiring.Suppressed); _hasMoved = true; }
/// <summary> /// Transforms the specified point <paramref name="p"/>. Here, the point transform is carried out in the same way as the vector transform. /// The transformation is carried out as a prepend transformation, i.e. result = p * matrix (p considered as horizontal vector). /// </summary> /// <param name="p">The point to transform.</param> /// <returns>The transformed point.</returns> public PointD2D Transform(PointD2D p) { double x = p.X; double y = p.Y; return(new PointD2D( x * M11 + y * M21, x * M12 + y * M22 )); }
public PathNodeGripHandle(IHitTestObject parent, PointD2D relPos, PointD2D gripCenter, double gripRadius) { _parent = parent; _drawrPosition = relPos; _fixrPosition = new PointD2D(relPos.X == 0 ? 1 : 0, relPos.Y == 0 ? 1 : 0); _fixaPosition = GraphObject.RelativeToAbsolutePosition(_fixrPosition, true); _gripCenter = gripCenter; _gripRadius = gripRadius; }
/// <summary> /// Activates this grip, providing the initial position of the mouse. /// </summary> /// <param name="initialPosition">Initial position of the mouse.</param> /// <param name="isActivatedUponCreation">If true the activation is called right after creation of this handle. If false, /// thie activation is due to a regular mouse click in this grip.</param> public void Activate(PointD2D initialPosition, bool isActivatedUponCreation) { _fixaPosition = GraphObject.RelativeLocalToAbsoluteParentCoordinates(_fixrPosition); initialPosition = _parent.Transformation.InverseTransformPoint(initialPosition); _initialMousePosition = GraphObject.ParentCoordinatesToLocalDifference(_fixaPosition, initialPosition); _initialSize = GraphObject.Size; _hasMoved = false; }
public RescaleGripHandle(IHitTestObject parent, PointD2D relPos, MatrixD2D spanningHalfYRhombus) { _parent = parent; _drawrPosition = relPos; _drawaPosition = GraphObject.RelativeToAbsolutePosition(_drawrPosition, true); _fixrPosition = new PointD2D(1 - relPos.X, 1 - relPos.Y); _fixaPosition = GraphObject.RelativeLocalToAbsoluteParentCoordinates(_fixrPosition); _spanningHalfYRhombus = spanningHalfYRhombus; }
/// <summary> /// Transforms the specified point <paramref name="p"/>. For a point transform, the offset elements M41..M43 are used. /// The transformation is carried out as a prepend transformation, i.e. result = p * matrix (p considered as horizontal vector). /// </summary> /// <param name="p">The point to transform. The z component is assumed to be 0.</param> /// <returns>The transformed point.</returns> public PointD3D Transform(PointD2D p) { double x = p.X; double y = p.Y; return(new PointD3D( x * M11 + y * M21 + M41, x * M12 + y * M22 + M42, x * M13 + y * M23 + M43 )); }
public void Activate(PointD2D initialPosition, bool isActivatedUponCreation) { _initialMousePosition = _parent.Transformation.InverseTransformPoint(initialPosition); _fixaPosition = GraphObject.RelativeLocalToAbsoluteParentCoordinates(_fixrPosition); _initialShear = GraphObject.Shear; _initialRotation = GraphObject.Rotation; _initialScaleX = GraphObject.ScaleX; _initialScaleY = GraphObject.ScaleY; _hasMoved = false; }
public bool IsBezierSegmentFlatEnough(PointD2D p0, PointD2D p1, PointD2D p2, PointD2D p3) { // First, test for absolute deviation of the curve if (_toleranceCriterium < double.MaxValue) { double ux = 3 * p1.X - 2 * p0.X - p3.X; ux *= ux; double uy = 3 * p1.Y - 2 * p0.Y - p3.Y; uy *= uy; double vx = 3 * p2.X - 2 * p3.X - p0.X; vx *= vx; double vy = 3 * p2.Y - 2 * p3.Y - p0.Y; vy *= vy; if (ux < vx) ux = vx; if (uy < vy) uy = vy; if ((ux + uy) > _toleranceCriterium) // tolerance here is 16*tol^2 (tol is the maximum absolute allowed deviation of the curve from the approximation) return false; } // now, test for the angle deviation of the curve var v30 = p3 - p0; if (0 == v30.X && 0 == v30.Y) return true; // there var v10 = p1 - p0; if (0 == v10.X && 0 == v10.Y) if ((0 != v10.X || 0 != v10.Y) && !IsAngleBelowCriterium(v30, v10)) return false; var v20 = p2 - p0; if ((0 != v20.X || 0 != v20.Y) && !IsAngleBelowCriterium(v30, v20)) return false; var v32 = p3 - p2; if ((0 != v32.X || 0 != v32.Y) && !IsAngleBelowCriterium(v30, v32)) return false; var v31 = p3 - p1; if ((0 != v31.X || 0 != v31.Y) && !IsAngleBelowCriterium(v30, v31)) return false; return true; }
public PointD2D GetRotatedByRad(double phi, PointD2D pivot) { var dx = X - pivot.X; var dy = Y - pivot.Y; if (phi != 0) { var cosphi = Math.Cos(phi); var sinphi = Math.Sin(phi); return(new PointD2D(pivot.X + (dx * cosphi - dy * sinphi), pivot.Y + (dx * sinphi + dy * cosphi))); } else { return(new PointD2D(X, Y)); } }
public override void OnMouseMove(PointD2D position, MouseEventArgs e) { base.OnMouseMove(position, e); _positionCurrentMouseInRootLayerCoordinates = _grac.ConvertMouseToRootLayerCoordinates(position); if (e.LeftButton == MouseButtonState.Pressed) { ModifyCurrentMousePrintAreaCoordinate(); _grac.RenderOverlay(); } else if (_currentPoint != 0) { _currentPoint = 0; _grac.RenderOverlay(); } }
/// <summary> /// Handles the click event by opening the text tool dialog. /// </summary> /// <param name="e">EventArgs.</param> /// <param name="position">Mouse position.</param> /// <returns>The mouse state handler for handling the next mouse events.</returns> public override void OnClick(PointD2D position, MouseButtonEventArgs e) { base.OnClick(position, e); _cachedActiveLayer = _grac.ActiveLayer; _cachedActiveLayerTransformation = _cachedActiveLayer.TransformationFromRootToHere(); _cachedActiveLayerTransformationGdi = (Matrix)_cachedActiveLayerTransformation; // get the page coordinates (in Point (1/72") units) var rootLayerCoord = _grac.ConvertMouseToRootLayerCoordinates(_positionLastMouseDownInMouseCoordinates); // with knowledge of the current active layer, calculate the layer coordinates from them var layerCoord = _cachedActiveLayerTransformation.InverseTransformPoint(rootLayerCoord); TextGraphic tgo = new TextGraphic(_grac.Doc.GetPropertyContext()); tgo.SetParentSize(_grac.ActiveLayer.Size, false); tgo.Position = layerCoord; tgo.ParentObject = _grac.ActiveLayer; // deselect the text tool _grac.SetGraphToolFromInternal(GraphToolType.ObjectPointer); object tgoo = tgo; if (Current.Gui.ShowDialog(ref tgoo, "Text", false)) { tgo = (TextGraphic)tgoo; if (tgo != null && !tgo.Empty) { _grac.ActiveLayer.GraphObjects.Add(tgo); } } /* TextControlDialog dlg = new TextControlDialog(_grac.Layers[_grac.CurrentLayerNumber],tgo); if(DialogResult.OK==dlg.ShowDialog(_grac.View.Window)) { // add the resulting textgraphobject to the layer if(!dlg.SimpleTextGraphics.Empty) { _grac.Layers[_grac.CurrentLayerNumber].GraphObjects.Add(dlg.SimpleTextGraphics); _grac.RefreshGraph(); } } */ _grac.SetGraphToolFromInternal(GraphToolType.ObjectPointer); }
public void FlattenPolyBezierCurve(PointD2D startPoint, IList<PointD2D> bezierPoints, List<PointD2D> flattenedList) { if (null == bezierPoints) throw new ArgumentNullException(nameof(bezierPoints)); if (bezierPoints.Count < 3 && 0 != (bezierPoints.Count) % 3) throw new ArgumentException("Array length has to be >=4 and has to be expressable as 1+3*k", nameof(bezierPoints)); // Flatten the first segment flattenedList.Add(bezierPoints[2]); FlattenBezierSegment(0, startPoint, bezierPoints[0], bezierPoints[1], bezierPoints[2], flattenedList, flattenedList.Count - 1); // now flatten the other segments for (int idx = 5; idx < bezierPoints.Count; idx += 3) // backward in order to have the insertionPoint not moved by the flattening { flattenedList.Add(bezierPoints[idx]); FlattenBezierSegment(0, bezierPoints[idx - 3], bezierPoints[idx - 2], bezierPoints[idx - 1], bezierPoints[idx], flattenedList, flattenedList.Count - 1); } }
/// <summary> /// Determines whether or not a given point (<c>point</c>) is into a <c>distance</c> to a finite line, that is spanned between /// two points <c>lineOrg</c> and <c>lineEnd</c>. /// </summary> /// <param name="point">Point under test.</param> /// <param name="distance">Distance.</param> /// <param name="lineOrg">Starting point of the line.</param> /// <param name="lineEnd">End point of the line.</param> /// <returns>True if the distance between point <c>point</c> and the line between <c>lineOrg</c> and <c>lineEnd</c> is less or equal to <c>distance</c>.</returns> public static bool IsPointIntoDistance(PointD2D point, double distance, PointD2D lineOrg, PointD2D lineEnd) { // first a quick test if the point is far outside the circle // that is spanned from the middle of the line and has at least // a radius of half of the line length plus the distance var xm = (lineOrg.X + lineEnd.X) / 2; var ym = (lineOrg.Y + lineEnd.Y) / 2; var r = Math.Abs(lineOrg.X - xm) + Math.Abs(lineOrg.Y - ym) + distance; if (Math.Max(Math.Abs(point.X - xm), Math.Abs(point.Y - ym)) > r) { return(false); } else { return(SquareDistanceLineToPoint(point, lineOrg, lineEnd) <= distance * distance); } }
/// <summary> /// Handles the MouseDown event when the plot point tool is selected /// </summary> /// <param name="position">Mouse position.</param> /// <param name="e">The mouse event args</param> public override void OnMouseDown(PointD2D position, MouseButtonEventArgs e) { base.OnMouseDown(position, e); if (null != _cachedActiveLayer && (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))) // if M is pressed, we don't move the cross, but instead we display not only the cross coordinates but also the difference { var printableCoord = _grac.ConvertMouseToRootLayerCoordinates(position); DisplayCrossCoordinatesAndDifference(printableCoord); } else { _cachedActiveLayer = _grac.ActiveLayer; _cachedActiveLayerTransformation = _cachedActiveLayer.TransformationFromRootToHere(); _cachedActiveLayerTransformationGdi = (Matrix)_cachedActiveLayerTransformation; _positionOfCrossInRootLayerCoordinates = _grac.ConvertMouseToRootLayerCoordinates(position); DisplayCrossCoordinates(); } _grac.RenderOverlay(); // no refresh necessary, only invalidate to show the cross } // end of function
public override void OnMouseDown(PointD2D position, MouseButtonEventArgs e) { base.OnMouseDown(position, e); if (e.ChangedButton == MouseButton.Left) { _cachedActiveLayer = _grac.ActiveLayer; _cachedActiveLayerTransformation = _cachedActiveLayer.TransformationFromRootToHere(); _cachedActiveLayerTransformationGdi = (Matrix)_cachedActiveLayerTransformation; _currentPoint = 0; // get the page coordinates (in Point (1/72") units) PointD2D rootLayerCoord = _positionCurrentMouseInRootLayerCoordinates; // with knowledge of the current active layer, calculate the layer coordinates from them PointD2D layerCoord = _cachedActiveLayerTransformation.InverseTransformPoint(rootLayerCoord); _Points[_currentPoint].LayerCoordinates = layerCoord; _Points[_currentPoint].RootLayerCoordinates = rootLayerCoord; _currentPoint++; } }
/// <summary> /// Determines whether or not a given point is into a certain distance of a polyline. /// </summary> /// <param name="point">The point.</param> /// <param name="distance">The distance.</param> /// <param name="polyline">The polyline.</param> /// <returns> /// <c>true</c> if the distance between point and polyline is less than or equal to the specified distance; otherwise, <c>false</c>. /// </returns> public static bool IsPointIntoDistance(PointD2D point, double distance, IEnumerable <PointD2D> polyline) { using (var iterator = polyline.GetEnumerator()) { if (!iterator.MoveNext()) { return(false); // no points in polyline } var prevPoint = iterator.Current; while (iterator.MoveNext()) { if (IsPointIntoDistance(point, distance, iterator.Current, prevPoint)) { return(true); } prevPoint = iterator.Current; } } return(false); }
public IList<PointD2D> FlattenPolyBezierCurve(PointD2D[] bezierPoints) { if (null == bezierPoints) throw new ArgumentNullException(nameof(bezierPoints)); if (bezierPoints.Length < 4 && 0 != (bezierPoints.Length - 1) % 3) throw new ArgumentException("Array length has to be >=4 and has to be expressable as 1+3*k", nameof(bezierPoints)); var list = new List<PointD2D>(); var segments = (bezierPoints.Length - 1) / 3; for (int i = 0; i < bezierPoints.Length; i += 3) list.Add(bezierPoints[i]); // add all curve points first for (int i = segments - 1; i > 0; --i) // backward in order to have the insertionPoint not moved by the flattening { int idx = i * 3; FlattenBezierSegment(0, bezierPoints[idx], bezierPoints[idx + 1], bezierPoints[idx + 2], bezierPoints[idx + 3], list, 1 + i); } return list; }
/// <summary> /// Calculates the dimensions of the greatest (by area) rectangle included in an outer rectangle, where the inner rectangle is rotated/sheared/scaled. /// </summary> /// <param name="outerRectangle">The outer rectangle.</param> /// <param name="sx">SX component of the transformation matrix that is applied to the inner rectangle.</param> /// <param name="rx">RX component of the transformation matrix that is applied to the inner rectangle.</param> /// <param name="ry">RY component of the transformation matrix that is applied to the inner rectangle.</param> /// <param name="sy">SY component of the transformation matrix that is applied to the inner rectangle.</param> /// <returns>The inner rectangle with the greatest area that fits (when transformed with the transformation elements) into the outer rectangle. /// The position of the returned rectangle is calculated so that it centers into the outer rectangle.</returns> /// <exception cref="System.ArgumentOutOfRangeException"> /// X-Size of outer rectangle must be > 0 /// or /// Y-Size of outer rectangle must be > 0 /// </exception> public static RectangleD2D GetIncludedTransformedRectangle(this RectangleD2D outerRectangle, double sx, double rx, double ry, double sy) { PointD2D outerRectangleSize = outerRectangle.Size; if (!(outerRectangleSize.X > 0)) { throw new ArgumentOutOfRangeException("X-Size of outer rectangle must be > 0"); } if (!(outerRectangleSize.Y > 0)) { throw new ArgumentOutOfRangeException("Y-Size of outer rectangle must be > 0"); } double a = Math.Abs(sx); double b = Math.Abs(rx); double c = Math.Abs(ry); double d = Math.Abs(sy); double maxArea = 0; double sizeX = 0, sizeY = 0; double x, y, area; { // solution 1, which touches all walls double bcMad = b * c - a * d; if (bcMad != 0) { x = (b * outerRectangleSize.Y - d * outerRectangleSize.X) / bcMad; y = (c * outerRectangleSize.X - a * outerRectangleSize.Y) / bcMad; area = x * y; if (maxArea < area) { maxArea = area; sizeX = x; sizeY = y; } } } { // solution2 (which does not touch the left and right walls of the outer retangle var eps2 = outerRectangleSize.X - outerRectangleSize.Y * (b * c + a * d) / (2 * c * d); if (eps2 >= 0 && eps2 < outerRectangleSize.X) { area = outerRectangleSize.Y * outerRectangleSize.Y / (4 * c * d); x = outerRectangleSize.Y / (2 * c); y = outerRectangleSize.Y / (2 * d); if (maxArea < area) { maxArea = area; sizeX = x; sizeY = y; } } } { // solution3 (which does not touch the top and bottom walls of the outer rectangle var eps3 = outerRectangleSize.Y - outerRectangleSize.X * (b * c + a * d) / (2 * a * b); if (eps3 >= 0 && eps3 < outerRectangleSize.Y) { area = outerRectangleSize.X * outerRectangleSize.X / (4 * a * b); x = outerRectangleSize.X / (2 * a); y = outerRectangleSize.X / (2 * b); if (maxArea < area) { maxArea = area; sizeX = x; sizeY = y; } } } var innerRect = new RectangleD2D(); innerRect.ExpandToInclude(new PointD2D(sx * sizeX + rx * sizeY, ry * sizeX + sy * sizeY)); innerRect.ExpandToInclude(new PointD2D(sx * sizeX, ry * sizeX)); innerRect.ExpandToInclude(new PointD2D(rx * sizeY, sy * sizeY)); var outerMiddle = outerRectangle.CenterCenter; var innerMiddle = innerRect.CenterCenter; return(new RectangleD2D((outerMiddle.X - innerMiddle.X), (outerMiddle.Y - innerMiddle.Y), sizeX, sizeY)); }
public PointD2D TransformVector(PointD2D pt) { return(new PointD2D(pt.X * sx + pt.Y * rx, pt.X * ry + pt.Y * sy)); }
public bool Contains(PointD2D p) { return(p.X >= X && p.Y >= Y && p.X <= Right && p.Y <= Bottom); }
private void EhGraphPanelSizeChanged(object sender, SizeChangedEventArgs e) { var s = e.NewSize; _guiCanvas.Clip = new RectangleGeometry(new Rect(0, 0, s.Width, s.Height)); if (!(s.Width > 0 && s.Height > 0)) return; _cachedGraphSize_96thInch = new PointD2D(s.Width, s.Height); var screenResolution = Current.Gui.ScreenResolutionDpi; var graphSizePixels = screenResolution * _cachedGraphSize_96thInch / 96.0; _cachedGraphSize_Pixels = new System.Drawing.Size((int)graphSizePixels.X, (int)graphSizePixels.Y); if (null != Controller) Controller.EhView_GraphPanelSizeChanged(); // inform controller ShowCachedGraphImage(); _isGraphUpToDate = false; if (_isGraphVisible) ((IGraphView)this).InvalidateCachedGraphBitmapAndRepaint(); }
/// <summary> /// Initializes a new instance of the <see cref="LineD3D"/> struct. /// </summary> /// <param name="p0">The starting point of the line.</param> /// <param name="p1">The end point of the line.</param> public LineD2D(PointD2D p0, PointD2D p1) { _p0 = p0; _p1 = p1; }
public static Point ToWpf(this Altaxo.Geometry.PointD2D pt) { return(new Point(pt.X, pt.Y)); }
/// <summary> /// Triangulates the specified polygons. The result are indexed triangles. /// </summary> /// <param name="polygons">The polygons to triangulate.</param> /// <returns>Instance of the <see cref="IndexedTriangles"/> class, which holds the triangle vertices as well as the indices.</returns> private static IndexedTriangles Triangulate(IList<PolygonClosedD2D> polygons) { var triangles = GetTriangles(polygons); var pointList = new List<PointD2D>(); var pointToIndex = new Dictionary<PointD2D, int>(); var indexList = new List<int>(); foreach (var triangulatedPolygon in triangles) { foreach (var triangle in triangulatedPolygon.Triangles) { var p0 = new PointD2D(triangle.Points[0].X, triangle.Points[0].Y); var p1 = new PointD2D(triangle.Points[1].X, triangle.Points[1].Y); var p2 = new PointD2D(triangle.Points[2].X, triangle.Points[2].Y); int i0, i1, i2; if (!pointToIndex.TryGetValue(p0, out i0)) { i0 = pointList.Count; pointToIndex.Add(p0, i0); pointList.Add(p0); } if (!pointToIndex.TryGetValue(p1, out i1)) { i1 = pointList.Count; pointToIndex.Add(p1, i1); pointList.Add(p1); } if (!pointToIndex.TryGetValue(p2, out i2)) { i2 = pointList.Count; pointToIndex.Add(p2, i2); pointList.Add(p2); } indexList.Add(i0); indexList.Add(i1); indexList.Add(i2); } } var indexedTriangles = new IndexedTriangles(pointList.ToArray(), indexList.ToArray()); return indexedTriangles; }
public PointD2D InverseTransformPoint(PointD2D pt) { return(new PointD2D(((pt.X - dx) * sy + (dy - pt.Y) * rx) / determinant, ((dx - pt.X) * ry + (pt.Y - dy) * sx) / determinant)); }
public PointD2D InverseTransformVector(PointD2D pt) { return(new PointD2D(((pt.X) * sy + (-pt.Y) * rx) / determinant, ((-pt.X) * ry + (pt.Y) * sx) / determinant)); }
/// <summary> /// Returns a new line with <see cref="P0"/> set to the provided value. /// </summary> /// <param name="p0">The value for <see cref="P0"/>.</param> /// <returns>A new line with <see cref="P0"/> set to the provided value.</returns> public LineD2D WithP0(PointD2D p0) { return(new LineD2D(p0, P1)); }
private PointD2D GetNormal(PointD2D polygonVector, bool isHole) { return(new PointD2D(polygonVector.Y, -polygonVector.X) / polygonVector.VectorLength); }
/// <summary> /// Adjusts the position and auto size of this group shape according to the contained elements. Must be called after changing any of the contained elements. /// </summary> public void AdjustPosition() { RectangleD2D bounds = RectangleD2D.Empty; bool boundsInitialized = false; foreach (var e in _groupedObjects) { var p1 = new PointD2D(0, 0); var p2 = new PointD2D(1, 0); var p3 = new PointD2D(0, 1); var p4 = new PointD2D(1, 1); p1 = e.RelativeLocalToAbsoluteParentCoordinates(p1); p2 = e.RelativeLocalToAbsoluteParentCoordinates(p2); p3 = e.RelativeLocalToAbsoluteParentCoordinates(p3); p4 = e.RelativeLocalToAbsoluteParentCoordinates(p4); if (boundsInitialized) { bounds.ExpandToInclude(p1); } else { bounds = new RectangleD2D(p1.X, p1.Y, 0, 0); boundsInitialized = true; } bounds.ExpandToInclude(p2); bounds.ExpandToInclude(p3); bounds.ExpandToInclude(p4); } if (bounds != Bounds) { // adjust position in this way that bounds.X and bounds.Y get zero var dx = bounds.X; var dy = bounds.Y; foreach (var e in _groupedObjects) { e.ShiftPosition(-dx, -dy); } this.ShiftPosition(dx, dy); ((ItemLocationDirectAutoSize)_location).SetSizeInAutoSizeMode(bounds.Size, false); bounds.Location = new PointD2D(0, 0); UpdateTransformationMatrix(); } }
/// <summary> /// Returns a new line with <see cref="P1"/> set to the provided value. /// </summary> /// <param name="p1">The value for <see cref="P1"/>.</param> /// <returns>A new line with <see cref="P1"/> set to the provided value.</returns> public LineD2D WithP1(PointD2D p1) { return(new LineD2D(P0, p1)); }
/// <summary> /// Gets a new instance with <see cref="ScreenOffset"/> set to the provided value. The screen offset has to be used only in extraordinary situation, e.g. for shifting to simulate multisampling; or for shifting to center the exported bitmap. /// It is not serialized either. /// </summary> /// <param name="screenOffset">The screen offset.</param> /// <returns>New instance of this class with <see cref="ScreenOffset"/> set to the provided value.</returns> public CameraBase WithScreenOffset(PointD2D screenOffset) { if (screenOffset != _screenOffset) { var result = (CameraBase)this.MemberwiseClone(); result._screenOffset = screenOffset; return result; } else { return this; } }
public PointD2D TransformPoint(PointD2D pt) { return(new PointD2D(pt.X * sx + pt.Y * rx + dx, pt.X * ry + pt.Y * sy + dy)); }