/// <summary> /// 根据从路径起点开始的路径长度, 获取路径上的位置 /// </summary> /// <param name="length"> 从路径起点开始的路径长度. 对于环状路径, 该长度可以为负值或大于路径长度的值 </param> /// <param name="startSegmentIndex"> 建议起始查找的路径段索引(负值表示无建议)</param> /// <param name="space"> 参数或返回值的相对空间 </param> /// <returns> 路径在指定长度处的位置 </returns> public Location GetLocationByLength(float length, int startSegmentIndex = -1, Space space = Space.World) { int lastSegmentIndex = _localSegments.Count - 1; ValidatePathLength(lastSegmentIndex); float totalLength = _localSegments[lastSegmentIndex].pathLength; if (space == Space.World) length /= absWorldScale; Location location = new Location(); // 处理计算长度 if (circular) { length = (totalLength + length % totalLength) % totalLength; } else { if (length <= 0) { return location; } if (length >= totalLength) { location.index = lastSegmentIndex; location.time = 1f; return location; } } // 如果建议开始索引无效, 则重新估算开始索引 if (startSegmentIndex < 0 || startSegmentIndex > lastSegmentIndex) { location.index = (int)(length / totalLength * lastSegmentIndex); } else { location.index = startSegmentIndex; } // 查找样条索引, 并计算样条位置 t if (_localSegments[location.index].pathLength > length) { do { if (location.index == 0) { location.time = _localSegments[0].GetLocationByLength(length); return location; } } while (_localSegments[--location.index].pathLength > length); location.time = _localSegments[location.index + 1].GetLocationByLength(length - _localSegments[location.index].pathLength); location.index++; } else { while (_localSegments[++location.index].pathLength < length) ; location.time = _localSegments[location.index].GetLocationByLength(length - _localSegments[location.index - 1].pathLength); } return location; }
/// <summary> /// 获取路径上指定位置的二阶导数 /// </summary> /// <param name="location"> 路径位置 </param> /// <param name="space"> 参数或返回值的相对空间 </param> /// <returns> 指定位置的二阶导数 </returns> public Vector3 GetSecondDerivative(Location location, Space space = Space.World) { Vector3 secondDerivative = _localSegments[location.index].GetSecondDerivative(location.time); if (space == Space.Self) return secondDerivative; else return TransformVector(secondDerivative); }
/// <summary> /// 获取路径上指定位置的切线. 切线是单位向量, 如果切线不存在返回 Vector3.zero /// </summary> /// <param name="location"> 路径位置 </param> /// <param name="space"> 参数或返回值的相对空间 </param> /// <returns> 指定位置的切线 </returns> public Vector3 GetTangent(Location location, Space space = Space.World) { Vector3 tangent = _localSegments[location.index].GetTangent(location.time); if (space == Space.Self) return tangent; else return TransformDirection(tangent); }
/// <summary> /// 获取路径上指定位置的点坐标 /// </summary> /// <param name="location"> 路径位置 </param> /// <param name="space"> 参数或返回值的相对空间 </param> /// <returns> 指定位置的点坐标 </returns> public Vector3 GetPoint(Location location, Space space = Space.World) { Vector3 point = _localSegments[location.index].GetPoint(location.time); if (space == Space.Self) return point; else return TransformPoint(point); }