using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace TProduct.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);
}
}
}