/// <summary> 一个点在经过一个矩阵变换之前的坐标 /// </summary> /// <param name="p">矩阵变换后的点</param> /// <param name="matrix">矩阵</param> /// <returns>矩阵变换前的点</returns> public static PointF PointBeforeMatrix(PointF p, DUIMatrix matrix) { double m11 = matrix.M11; double m12 = matrix.M12; double m21 = matrix.M21; double m22 = matrix.M22; double m31 = matrix.M31; double m32 = matrix.M32; return(new PointF((float)((p.Y * m21 - m32 * m21 - p.X * m22 + m31 * m22) / (m12 * m21 - m11 * m22)), (float)((p.Y * m11 - m32 * m11 - p.X * m12 + m31 * m12) / (m22 * m11 - m21 * m12)))); }
/// <summary> 一个点经过一个矩阵变换到达的新坐标 /// </summary> /// <param name="p">点</param> /// <param name="matrix">矩阵</param> /// <returns>矩阵变换后的点</returns> public static PointF PointAfterMatrix(PointF p, DUIMatrix matrix) { double m11 = matrix.M11; double m12 = matrix.M12; double m21 = matrix.M21; double m22 = matrix.M22; double m31 = matrix.M31; double m32 = matrix.M32; return(new PointF((float)(p.X * m11 + p.Y * m21 + m31), (float)(p.X * m12 + p.Y * m22 + m32))); }
public override void DoOffsetOther(float offsetX, float offsetY, DUIAnyBounds anyBounds) { DUIAnyBoundsPolygon anyBoundsPolygon = (DUIAnyBoundsPolygon)anyBounds; DUIMatrix m = new DUIMatrix(); m.Rotate(this.Rotate); PointF p = MatrixTools.PointAfterMatrix(new PointF(offsetX, offsetY), m); anyBoundsPolygon.Polygon = this.Polygon.Select(pl => new PointF(pl.X + p.X, pl.Y + p.Y)).ToArray(); RectangleF bounds = PolygonTools.GetPolygonRect(anyBoundsPolygon.Polygon); }
public override void DoOffsetPoint(float offsetX, float offsetY, DUIAnyBounds anyBounds) { offsetX = GetLimitPolygonPointLeftOffset(offsetX); offsetY = GetLimitPolygonPointTopOffset(offsetY); DUIAnyBoundsPolygon anyBoundsPolygon = (DUIAnyBoundsPolygon)anyBounds; RectangleF lastPolygonBounds = PolygonTools.GetPolygonRect(this.Polygon); PointF[] polygon = this.Polygon.Select(p => new PointF(p.X, p.Y)).ToArray(); polygon[this.hoverPointIndex].X += offsetX; polygon[this.hoverPointIndex].Y += offsetY; RectangleF polygonBounds = PolygonTools.GetPolygonRect(polygon); DUIMatrix m = new DUIMatrix(); m.Rotate(this.Rotate); PointF offset = MatrixTools.PointAfterMatrix(new PointF(polygonBounds.X - lastPolygonBounds.X, polygonBounds.Y - lastPolygonBounds.Y), m); anyBoundsPolygon.Polygon = polygon.Select(pl => new PointF(pl.X + offset.X - (polygonBounds.X - lastPolygonBounds.X), pl.Y + offset.Y - (polygonBounds.Y - lastPolygonBounds.Y))).ToArray(); }
protected internal override void SetCenterChanged(PointF center) { float lastX = this.x; float lastY = this.y; PointF p = this.ClientBounds.Location; DUIMatrix matrix = new DUIMatrix(); matrix.Translate(this.ClientBounds.X + this.CenterX, this.ClientBounds.Y + this.CenterY); matrix.Rotate(this.Rotate); matrix.Skew(this.SkewX, this.SkewY); matrix.Scale(this.ScaleX, this.ScaleY); matrix.Translate(-(this.ClientBounds.X + this.CenterX), -(this.ClientBounds.Y + this.CenterY)); p = MatrixTools.PointAfterMatrix(p, matrix); matrix.Reset(); matrix.Translate(center.X, center.Y); matrix.Scale(1 / this.ScaleX, 1 / this.ScaleY); matrix.Skew(-this.SkewX, -this.SkewY); var s = (float)(Math.Tan(-this.SkewX) * Math.Tan(this.SkewY) + 1); matrix.Scale(1 / s, 1 / s); matrix.Rotate(-this.Rotate); matrix.Translate(-center.X, -center.Y); p = MatrixTools.PointAfterMatrix(p, matrix); float x = p.X - this.BorderWidth; float y = p.Y - this.BorderWidth; var polygon = this.Polygon.Select(pl => new PointF(pl.X + x - lastX, pl.Y + y - lastY)).ToArray(); this.SetBoundsChanged( center.X - p.X , center.Y - p.Y , this.Rotate , 0 , 0 , 0 , 0 , polygon , DUIBoundsPolygonSpecified.Center | DUIBoundsPolygonSpecified.Polygon | DUIBoundsPolygonSpecified.RotateAngle); }
/// <summary> 三对点仿射变换 /// </summary> /// <param name="srcTriangle"> 原始三个点</param> /// <param name="destTriangle">目标三个点</param> /// <returns>仿射变换2x3矩阵</returns> public static DUIMatrix ThreePointsAffine(PointF[] srcTriangle, PointF[] destTriangle) { #region 对点仿射变换 PointF s1 = srcTriangle[0]; PointF s2 = srcTriangle[1]; PointF s3 = srcTriangle[2]; PointF t1 = destTriangle[0]; PointF t2 = destTriangle[1]; PointF t3 = destTriangle[2]; double m11 = 1; double m12 = 0; double m21 = 0; double m22 = 1; double m31 = 0; double m32 = 0; m21 = (t1.X * s1.X - t3.X * s1.X - t1.X * s2.X + t3.X * s2.X - t1.X * s1.X + t2.X * s1.X + t1.X * s3.X - t2.X * s3.X) / (s2.Y * s1.X - s1.Y * s1.X - s2.Y * s3.X + s1.Y * s3.X - s3.Y * s1.X + s1.Y * s1.X + s3.Y * s2.X - s1.Y * s2.X); if (s1.X - s2.X != 0) { m11 = (m21 * s2.Y - m21 * s1.Y + t1.X - t2.X) / (s1.X - s2.X); } else if (s1.X - s3.X != 0) { m11 = (m21 * s3.Y - m21 * s1.Y + t1.X - t3.X) / (s1.X - s3.X); } else if (s2.X - s3.X != 0) { m11 = (m21 * s3.Y - m21 * s2.Y + t2.X - t3.X) / (s2.X - s3.X); } m31 = t1.X - m11 * s1.X - m21 * s1.Y; //m31 = // t2.X // - m11 * s2.X // - m21 * s2.Y; //m31 // = t3.X // - m11 * s3.X // - m21 * s3.Y; m22 = (t1.Y * s1.X - t3.Y * s1.X - t1.Y * s2.X + t3.Y * s2.X - t1.Y * s1.X + t2.Y * s1.X + t1.Y * s3.X - t2.Y * s3.X) / (s2.Y * s1.X - s1.Y * s1.X - s2.Y * s3.X + s1.Y * s3.X - s3.Y * s1.X + s1.Y * s1.X + s3.Y * s2.X - s1.Y * s2.X); if (s1.X - s2.X != 0) { m12 = (m22 * s2.Y - m22 * s1.Y + t1.Y - t2.Y) / (s1.X - s2.X); } else if (s1.X - s3.X != 0) { m12 = (m22 * s3.Y - m22 * s1.Y + t1.Y - t3.Y) / (s1.X - s3.X); } else if (s2.X - s3.X != 0) { m12 = (m22 * s3.Y - m22 * s2.Y + t2.Y - t3.Y) / (s2.X - s3.X); } m32 = t1.Y - m12 * s1.X - m22 * s1.Y; //m32 = // t2.Y // - m12 * s2.X // - m22 * s2.Y; //m32 // = t3.Y // - m12 * s3.X // - m22 * s3.Y; #endregion DUIMatrix m = new DUIMatrix(); if (destTriangle != srcTriangle) { m11 = double.IsNaN(m11) ? 1 : m11; m12 = double.IsNaN(m12) ? 0 : m12; m21 = double.IsNaN(m21) ? 0 : m21; m22 = double.IsNaN(m22) ? 1 : m22; m31 = double.IsNaN(m31) ? 0 : m31; m32 = double.IsNaN(m32) ? 0 : m32; m = new DUIMatrix((float)m11, (float)m12, (float)m21, (float)m22, (float)m31, (float)m32); } return(m); }