1.点到直线的距离
/// <summary>
/// 某个点到线段上的距离
/// </summary>
/// <param name="point"></param>
/// <param name="linePointA"></param>
/// <param name="linePointB"></param>
/// <returns></returns>
public static double DisPoint2Line(Vector2 point, Vector2 linePointA, Vector2 linePointB)
{
double dis = 0;
if (linePointA.x == linePointB.x)
{
dis = Math.Abs(point.x - linePointA.x);
return dis;
}
double lineK = (linePointB.y - linePointA.y) / (linePointB.x - linePointA.x);
double lineC = (linePointB.x * linePointA.y - linePointA.x * linePointB.y) / (linePointB.x - linePointA.x);
dis = Math.Abs(lineK * point.x - point.y + lineC) / (Math.Sqrt(lineK * lineK + 1));
return dis;
}
2.获取点在直线上的垂直投影点
/// <summary>
/// 获得某点在一个直线上的投影
/// </summary>
/// <param name="point"></param>
/// <param name="linePoint1"></param>
/// <param name="linePoint2"></param>
/// <returns></returns>
public static Vector3 GetProjectivePoint(Vector3 point, Vector3 linePoint1, Vector3 linePoint2)
{
Vector3 target;
Vector3 lineDir = (linePoint2 - linePoint1).normalized;
Vector3 projectiveDir = Quaternion.Euler(0, 90, 0) * lineDir;
Vector3 point2 = point + projectiveDir;
target = GetIntersectionByPoints(point, point2, linePoint1, linePoint2);
return target;
}
3.获取两直线交点
区分直线和线段
/// <summary>
/// 得到两直线交点的方法
/// </summary>
/// <param name="lineFirstStart"> 第一条线的一个点 </param>
/// <param name="lineFirstEnd"> 第一条线的另外一个点 </param>
/// <param name="lineSecondStart"> 第二条线的一个点 </param>
/// <param name="lineSecondEnd"> 第二条线的另外一个点 </param>
/// <returns></returns>
public static Vector3 GetIntersectionByPoints(Vector3 lineFirstStart, Vector3 lineFirstEnd, Vector3 lineSecondStart,
Vector3 lineSecondEnd)
{
float y = lineFirstStart.y;
double a = 0, b = 0;
int state = 0;
if (lineFirstStart.x != lineFirstEnd.x)
{
a = (lineFirstEnd.z - lineFirstStart.z) / (lineFirstEnd.x - lineFirstStart.x);
state |= 1;
}
if (lineSecondStart.x != lineSecondEnd.x)
{
b = (lineSecondEnd.z - lineSecondStart.z) / (lineSecondEnd.x - lineSecondStart.x);
state |= 2;
}
switch (state)
{
case 0:
{
if (lineFirstStart.x == lineSecondStart.x)
{
return Vector3.zero;
}
else
{
return Vector3.zero;
}
}
case 1:
{
double x = lineSecondStart.x;
double z = (lineFirstStart.x - x) * (-a) + lineFirstStart.z;
return new Vector3((float)x, y, (float)z);
}
case 2:
{
double x = lineFirstStart.x;
double z = (lineSecondStart.x - x) * (-b) + lineSecondStart.z;
return new Vector3((float)x, y, (float)z);
}
case 3:
{
if (Mathf.Abs((float)(a - b)) < 0.0001)
{
return Vector3.zero;
}
double x = (a * lineFirstStart.x - b * lineSecondStart.x - lineFirstStart.z + lineSecondStart.z) / (a - b);
double z = a * x - a * lineFirstStart.x + lineFirstStart.z;
return new Vector3((float)x, y, (float)z);
}
}
return Vector3.zero;
}
4.获取线段与直线的交点
public static Vector3? GetIntersectonBetweenLineAndSegment(Vector3 linePointA, Vector3 linePointB, Vector3 segmentPointA, Vector3 segmentPointB)
{
// 先求两直线交点 再判断交点是否在线段上
Vector3? intersection = GetIntersectionByPoints(linePointA, linePointB, segmentPointA, segmentPointB);
if (intersection != Vector3.zero)
{
//if (CheckPointInSegement(segmentPointA, segmentPointB, intersection.Value))
//{
// Debug.Log(string.Format("segmentStart: {0} segmentEnd: {1} intersection:{2}", segmentPointA.ToString("f4"), segmentPointB.ToString("f4"), intersection.Value.ToString("f4")));
// return intersection;
//}
if (IsPointInsideSegment(new List<Vector2>() { segmentPointA.ToVector2XZ(), segmentPointB.ToVector2XZ() }, intersection.Value.ToVector2XZ()))
{
//Debug.Log(string.Format("segmentStart: {0} segmentEnd: {1} intersection:{2}", segmentPointA.ToString("f4"), segmentPointB.ToString("f4"), intersection.Value.ToString("f4")));
return intersection;
}
}
return null;
}
5.点是否在线段上(含两端点)
public static bool IsPointInsideSegment(IEnumerable<Vector2> segment, Vector2 point)
{
// 线段顶点数目必须等于2
if (segment.Count() != 2)
{
Debug.LogError(string.Format("Segment must have only 2 vertex, current segment have {0} vertex!", segment.Count()));
return false;
}
if (Mathf.Approximately((point - segment.First()).magnitude + (point - segment.Last()).magnitude, (segment.First() - segment.Last()).magnitude))
return true;
else
return false;
}
6.检测某个点是否在线段上
public static bool CheckPointInSegement(Vector2 lineStart, Vector2 lineEnd, Vector2 point)
{
// 误差范围
if (DisPoint2Line(point, lineStart, lineEnd) >= 0.002f)
{
return false;
}
Vector2 p2Start = (lineStart - point).normalized;
Vector2 p2End = (lineEnd - point).normalized;
if (Vector2.Dot(p2End, p2Start) <= 0)
{
return true;
}
else
{
return false;
}
}
- 判断两线段是否相交
//firstlineStart, firstlineEnd为一条线段两端点 SecondlineStart, SecondlineEnd为另一条线段的两端点 相交返回true, 不相交返回false
public static bool CheckTwoSegmentCrose(Vector2 firstlineStart, Vector2 firstlineEnd, Vector2 SecondlineStart, Vector2 SecondlineEnd)
{
if (max(firstlineStart.x, firstlineEnd.x) < min(SecondlineStart.x, SecondlineEnd.x))
{
return false;
}
if (max(firstlineStart.y, firstlineEnd.y) < min(SecondlineStart.y, SecondlineEnd.y))
{
return false;
}
if (max(SecondlineStart.x, SecondlineEnd.x) < min(firstlineStart.x, firstlineEnd.x))
{
return false;
}
if (max(SecondlineStart.y, SecondlineEnd.y) < min(firstlineStart.y, firstlineEnd.y))
{
return false;
}
if (mult(SecondlineStart, firstlineEnd, firstlineStart) * mult(firstlineEnd, SecondlineEnd, firstlineStart) < 0)
{
return false;
}
if (mult(firstlineStart, SecondlineEnd, SecondlineStart) * mult(SecondlineEnd, firstlineEnd, SecondlineStart) < 0)
{
return false;
}
return true;
}
- 判断两个线段是否端点相连
// 判断两条线段是否相连
public static bool CheckTwoSegmentSharePoint(Vector2 firstlineStart, Vector2 firstlineEnd, Vector2 SecondlineStart, Vector2 SecondlineEnd)
{
return firstlineStart == SecondlineStart || firstlineStart == SecondlineEnd || firstlineEnd == SecondlineStart || firstlineEnd == SecondlineEnd;
}
9.判断两线段是否共线
/// <summary>
/// 判断两个线段是否共线
/// </summary>
/// <param name="firstWall"></param>
/// <param name="secondWall"></param>
/// <returns></returns>
public static bool CheckTwoSegmentShareLine(Vector2 lineAStart, Vector2 lineAEnd, Vector2 lineBStart, Vector2 lineBEnd)
{
Vector2 firstWallDir = (lineAEnd - lineAStart).normalized;
Vector2 secondWallDir = (lineBEnd - lineBStart).normalized;
//Debug.Log(string.Format("aStart:{2] end:{3} bStart:{4} end:{5} firstWallDir:{0} secondWallDir:{1}",
// firstWallDir.ToString("f4"), secondWallDir.ToString("f4"), lineAStart.ToString("f4"), lineAEnd.ToString("f4"), lineBStart.ToString("f4"), lineBEnd.ToString("f4")));
//if (DisPoint2Line(lineAStart, lineBStart, lineBEnd)>0.001f|| DisPoint2Line(lineAEnd, lineBStart, lineBEnd)>0.001f)
// return false;
//// 没有加检测
//return Vector3.Distance(firstWallDir, secondWallDir) < 0.001f || Vector3.Distance(firstWallDir, -secondWallDir) < 0.001f;
return (CheckThreePointShareLine(lineAStart, lineAEnd, lineBStart)) && (CheckThreePointShareLine(lineAStart, lineAEnd, lineBEnd));
}
10.判断三点是否共线
/// <summary>
/// 判断三点是否共线
/// </summary>
/// <param name="lineA"></param>
/// <param name="lineB"></param>
/// <param name="lineC"></param>
/// <returns></returns>
public static bool CheckThreePointShareLine(Vector2 lineA, Vector2 lineB, Vector2 lineC)
{
if (lineA != lineB && lineB != lineC && lineC != lineA)//这里修改了一下
{
Vector2 a2b = (lineB - lineA).normalized;
Vector2 c2b = (lineB - lineC).normalized;
//Debug.Log(a2b.ToString("f6") + " " + c2b.ToString("f6"));
return (a2b == c2b) || (a2b == -c2b);
}
else
{
return true;
}
}
11.判断两条线段是否共线且存在重叠
/// <summary>
/// 判断两条选段是否有重叠
/// </summary>
/// <param name="lineAStart"></param>
/// <param name="lineAEnd"></param>
/// <param name="lineBStart"></param>
/// <param name="lineBEnd"></param>
/// <returns></returns>
public static bool CheckTwoSegmentOverlap(Vector2 lineAStart, Vector2 lineAEnd, Vector2 lineBStart, Vector2 lineBEnd)
{
if (CheckTwoSegmentShareLine(lineAStart, lineAEnd, lineBStart, lineBEnd))
{
//Debug.Log("ShareLine");
Vector2 s2s = (lineBStart - lineAStart).normalized;
Vector2 s2e = (lineBEnd - lineAStart).normalized;
Vector2 e2s = (lineBStart - lineAEnd).normalized;
Vector2 e2e = (lineBEnd - lineAEnd).normalized;
if (s2s == s2e && s2e == e2s && e2s == e2e)
{
return false;
}
return true;
}
return false;
}