using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; namespace IStation.Extensions { /// /// PointF 坐标拓展 /// public static class PointFExtension { /// /// 获取矩形 /// /// /// /// public static RectangleF GetRectangleF(this PointF p1, PointF p2) { float x = p1.X < p2.X ? p1.X : p2.X; float y = p1.Y < p2.Y ? p1.Y : p2.Y; float width = Math.Abs(p1.X - p2.X); float height = Math.Abs(p1.Y - p2.Y); return new RectangleF(x, y, width, height); } /// /// 计算两点间的距离 /// /// /// /// public static double DistanceTo(this PointF p1, PointF p2) { return Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)); } /// /// 计算点与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.DistanceTo(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.DistanceTo(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); } } }