sdsandbox-rl-scripts/Scripts/Lines.cs

101 lines
1.9 KiB
C#
Executable File

using UnityEngine;
using System.Collections;
//3d line
public class Line3d
{
public Line3d() {}
public Line3d(ref Vector3 a, ref Vector3 b)
{
ConstructLine(ref a, ref b);
}
//allow a line to be recomputed
public void ConstructLine(ref Vector3 a, ref Vector3 b)
{
m_origin = a;
m_dir = a - b;
m_dir.Normalize();
}
//produce a vector normal to this line passing through this point.
public Vector3 ClosestVectorTo(ref Vector3 point)
{
Vector3 deltaPoint = m_origin - point;
float dot = Vector3.Dot(deltaPoint, m_dir);
return (m_dir * dot) - deltaPoint;
}
//transform the point by the normal vector that places it on the line
public Vector3 ClosestPointOnLineTo(ref Vector3 point)
{
Vector3 vectorTo = ClosestVectorTo(ref point);
return point - vectorTo;
}
public float AbsAngleBetween(ref Line3d l)
{
return Mathf.Abs(Vector3.Angle( m_dir, l.m_dir));
}
public Vector3 m_origin, m_dir;
};
public class LineSeg3d : Line3d
{
public LineSeg3d(){}
public LineSeg3d(ref Vector3 a, ref Vector3 b)
{
ConstructLineSeg(ref a, ref b);
}
public void ConstructLineSeg(ref Vector3 a, ref Vector3 b)
{
ConstructLine(ref a, ref b);
m_end = b;
m_length = (a - b).magnitude;
}
public enum SegResult
{
OnSpan,
LessThanOrigin,
GreaterThanEnd,
}
//find the closest point, clamping it to the ends
public Vector3 ClosestPointOnSegmentTo(ref Vector3 point, ref SegResult res)
{
Vector3 deltaPoint = m_origin - point;
float dot = Vector3.Dot(deltaPoint, m_dir);
//clamp to the ends of the line segment
if(dot <= 0.0f)
{
res = SegResult.LessThanOrigin;
return m_origin;
}
if(dot >= m_length)
{
res = SegResult.GreaterThanEnd;
return m_end;
}
res = SegResult.OnSpan;
Vector3 vectorTo = (m_dir * dot) - deltaPoint;
return point - vectorTo;
}
public void Draw(Color c)
{
Debug.DrawLine(m_origin, m_end, c);
}
public float m_length;
public Vector3 m_end;
};