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.獲取兩直線交點
區(qū)分直線和線段
/// <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)
{
// 線段頂點數(shù)目必須等于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;
}