using System;
|
using System.Collections.Generic;
|
using System.Drawing;
|
using System.Linq;
|
using System.Text;
|
|
namespace Eventech.DynPicture.Model
|
{
|
/// <summary>
|
/// 点坐标拓展
|
/// </summary>
|
public static class PointFExtension
|
{
|
/// <summary>
|
/// 计算两点间的距离
|
/// </summary>
|
/// <param name="p1"></param>
|
/// <param name="p2"></param>
|
/// <returns></returns>
|
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));
|
}
|
|
/// <summary>
|
/// 计算点与X轴正方向的夹角弧度
|
/// </summary>
|
/// <param name="pf"></param>
|
/// <returns>夹角弧度</returns>
|
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;
|
}
|
|
/// <summary>
|
/// 计算点相对于当前点的顺时针角度
|
/// </summary>
|
/// <param name="o"></param>
|
/// <param name="p"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 获取相对当前点的X轴点
|
/// </summary>
|
/// <param name="o"></param>
|
/// <param name="p"></param>
|
/// <returns></returns>
|
public static PointF GetXPoint(this PointF o, PointF p)
|
{
|
var distance = (float)o.DistanceTo(p);
|
return new PointF(o.X + distance, o.Y);
|
}
|
|
/// <summary>
|
/// 计算以当前点为中心旋转角度angle后的新坐标
|
/// </summary>
|
/// <param name="A">旋转中心坐标</param>
|
/// <param name="P">待旋转的坐标</param>
|
/// <param name="angle">旋转角度</param>
|
/// <param name="isClockWise">true:顺时针/false:逆时针</param>
|
/// <returns></returns>
|
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);
|
}
|
|
|
|
}
|
}
|