/// <summary> /// 通过距离起点的距离,获取线上的点的坐标、斜率、圆心到坐标的单位向量(垂直于斜率) /// </summary> public void GetSampleAtDistance(float distance, out Vector3 position, out Vector3 tangent, out Vector3 emit) { LinkedListNode <PBCircleNode> listNode = nodes.First; PBCircleNode startNode = null; PBCircleNode endNode = null; while (listNode != null) { if (distance < listNode.Value.distance) { startNode = listNode.Previous.Value; endNode = listNode.Value; break; } listNode = listNode.Next; } if (startNode == null) { throw new ArgumentException(string.Format("Distance must be less than curve length. Curve length: {0}, distance: {1}", nodes.Last.Value.distance, distance)); } float t = (distance - startNode.distance) / (endNode.distance - startNode.distance); if (startNode.ConnectLine(endNode)) { //直线 position = Vector3.Lerp(startNode.position, endNode.position, t); tangent = startNode.tangent; emit = (startNode.position - startNode.circle.center).normalized; } else { //圆弧 PBCircle circle = startNode.circle; float angle = startNode.angle + t * startNode.deltaAngle(endNode); Vector3 r = Quaternion.AngleAxis(angle, circle.forward) * circle.up; r.Normalize(); position = circle.center + r * circle.radius; tangent = Quaternion.AngleAxis(angle, circle.forward) * (-circle.right); emit = r; } }
public static LinkedList <PBCircleNode> Build(PBCircle[] circles, PBCircleCurveType type) { LinkedList <PBCircleNode> nodes = null; switch (type) { case PBCircleCurveType.OneCircle: nodes = BuildForOne(circles); break; case PBCircleCurveType.Line: nodes = BuildForLine(circles); break; case PBCircleCurveType.Enclosed: nodes = BuildForEnclosed(circles); break; } //compute distance for nodes LinkedListNode <PBCircleNode> listNode = nodes.First; listNode.Value.distance = 0; listNode = listNode.Next; while (listNode != null) { PBCircleNode node = listNode.Value; PBCircleNode preNode = listNode.Previous.Value; if (node.ConnectLine(preNode)) { //直线 node.distance = preNode.distance + Vector3.Distance(node.position, preNode.position); //Debug.Log(">>>>>>>1 distance: " + node.distance); } else { //圆弧 float radius = node.circle.radius; node.distance = preNode.distance + preNode.deltaAngle(node) * Mathf.Deg2Rad * radius; //Debug.Log(">>>>>>>2 distance: " + node.distance); } listNode = listNode.Next; } return(nodes); }