namespace Yw.WinFrmUI.HydroL2d { /// /// 点坐标拓展 /// internal static class PointFExtension { /// /// 是否无效 /// public static bool InValid(this PointF rhs) { if (rhs.X.Invalid()) { return true; } if (rhs.Y.Invalid()) { return true; } return false; } /// /// 是否有效 /// public static bool Valid(this PointF rhs) { return !rhs.InValid(); } /// /// 获取中心 /// public static PointF GetCenter(this PointF rhs, PointF other) { return new PointF((rhs.X + other.X) / 2f, (rhs.Y + other.Y) / 2f); } /// /// 计算两点间的距离 /// /// 当前点 /// 其他点 /// public static double Distance(this PointF rhs, PointF other) { return Math.Sqrt(Math.Pow(rhs.X - other.X, 2) + Math.Pow(rhs.Y - other.Y, 2)); } /// /// 计算点与X轴正方向的夹角弧度 /// /// /// 夹角弧度 public static double RadPox(this PointF pf) { var x = pf.X; var y = pf.Y; //P在(0,0)的情况 if (x == 0 && y == 0) return 0; //P在四个坐标轴上的情况:x正、x负、y正、y负 if (y == 0 && x > 0) return 0; if (y == 0 && x < 0) return Math.PI; if (x == 0 && y > 0) return Math.PI / 2; if (x == 0 && y < 0) return Math.PI / 2 * 3; //点在第一、二、三、四象限时的情况 if (x > 0 && y > 0) return Math.Atan(y / x); if (x < 0 && y > 0) return Math.PI - Math.Atan(y / -x); if (x < 0 && y < 0) return Math.PI + Math.Atan(-y / -x); if (x > 0 && y < 0) return Math.PI * 2 - Math.Atan(-y / x); return 0; } /// /// /// public static double AnglePox(this PointF pf) { var x = pf.X; var y = pf.Y; //P在(0,0)的情况 if (x == 0 && y == 0) return 0; //P在四个坐标轴上的情况:x正、x负、y正、y负 if (y == 0 && x > 0) return 0; if (y == 0 && x < 0) return 180; if (x == 0 && y > 0) return 270; if (x == 0 && y < 0) return 90; //点在第一、二、三、四象限时的情况 if (x > 0 && y > 0) return Math.Atan(y / x); if (x < 0 && y > 0) return Math.Atan(y / -x) * 180 - 180; if (x < 0 && y < 0) return 180 - Math.Atan(-y / -x) / 180; if (x > 0 && y < 0) return Math.PI * 2 - Math.Atan(-y / x); return 0; } /// /// 计算点相对于当前点的顺时针角度 /// /// /// /// public static double AngleClockWise(this PointF o, PointF p) { var x = p.X - o.X; var y = p.Y - o.Y; //P在(0,0)的情况 if (x == 0 && y == 0) return 0; //P在四个坐标轴上的情况:x正、x负、y正、y负 if (y == 0 && x > 0) return 0; if (y == 0 && x < 0) return 180; if (x == 0 && y > 0) return 90; if (x == 0 && y < 0) return -90; //点在第一、二、三、四象限时的情况 if (x > 0 && y > 0) return Math.Atan(y / x) * 180 / Math.PI; if (x < 0 && y > 0) return 180 - Math.Atan(y / -x) * 180 / Math.PI; if (x < 0 && y < 0) return Math.Atan(-y / -x) * 180 / Math.PI - 180; if (x > 0 && y < 0) return -Math.Atan(-y / x) * 180 / Math.PI; return 0; } /// /// 获取相对当前点的X轴点 /// /// /// /// public static PointF GetXPoint(this PointF o, PointF p) { var distance = (float)o.Distance(p); return new PointF(o.X + distance, o.Y); } /// /// 计算以当前点为中心旋转角度angle后的新坐标 /// /// 旋转中心坐标 /// 待旋转的坐标 /// 旋转角度 /// true:顺时针/false:逆时针 /// public static PointF RotatePointF(this PointF A, PointF P, float angle, bool isClockWise = true) { var rad = angle * Math.PI / 180; //点Temp1 PointF temp1 = new PointF(P.X - A.X, P.Y - A.Y); //点Temp1到原点的长度 double lenO2Temp1 = temp1.Distance(new PointF(0, 0)); //∠T1OX弧度 double angT1OX = temp1.RadPox(); //∠T2OX弧度(T2为T1以O为圆心旋转弧度rad) double angT2OX = angT1OX - (!isClockWise ? 1 : -1) * rad; //点Temp2 PointF Temp2 = new PointF((float)(lenO2Temp1 * Math.Cos(angT2OX)), (float)(lenO2Temp1 * Math.Sin(angT2OX))); //点Q return new PointF(Temp2.X + A.X, Temp2.Y + A.Y); } } }