沿着地形表面的贝塞尔曲线

时间:2019-03-11 14:08:18

标签: c# unity3d mathematical-optimization bezier raycasting

如果我将一个bezier曲线(设置起点和终点)绘制到Unity Terrain,并且希望该曲线从地面起伏,那是最好的方法。

现在我部分地做到了这一点,(需要将groundedPoints中的新点连接为新的贝塞尔曲线)

int SegmentCount = Mathf.Floor(BezierLength / SegmentLength);
//Rounded to the next lower integer
var groundedPoints = new List<Vector3>();

for(int i =0; i<SegmentCount;i++){
  Vector3 p = GetPoint(BezierPoints,i / SegmentCount);
    p = p.RayCastDown();
    //RayCasting Down to get the Point on the Terrain
  if(i == 0 || i < SegmentCount -1){
    groundedPoints.Add(p);
  }else{
    if(p.y != groundedPoints[groundedPoints.Count-1].y){
      groundedPoints.Add(p);
      }
   }
}

它现在还不算准确,但不一定是真正准确的解决方案。

也许有人可以给我提示吗?谢谢

1 个答案:

答案 0 :(得分:1)

首先,我建议使用Centripetal Catmull–Rom spline,因为它遵循更严格的点,并且需要更少的点来生成(也仅在p1和p2之间绘制),但是我不知道您要达到什么目的:

我会将贝塞尔曲线转换为2d贝塞尔曲线,并且只能在2d空间中使用它,然后在绘制(以可视方式渲染)时,可以使用https://docs.unity3d.com/ScriptReference/Terrain.SampleHeight.html为其赋予Y值

我用样条线执行此操作,并且最终(道路生成)给出了相当准确的样条线

请注意!: 隐式的Vector2和Vector3转换将无法满足您的需求,您需要添加扩展方法以将Vector3转换为Vector2 :) (Vector(x,y,z)将是Vector(x,y),但您需要Vector(x,z))

编辑1:

代码示例如何通过Terrain.SampleHeight();通过Vector2坐标确定您确实在地形上方来读取地形实际高度,如果Vector2不在地形上方,它将给您返回null或壁橱的地形高度,我不确定是哪一个atm(现在无法对其进行测试):)

public static float GetPoint_On_Terrain(Vector2 point){
    float terrainHeightAtPoint = Terrain.activeTerrain.SampleHeight(new Vector3(point.x, 0, point.y));
    return new Vector3(point.x, terrainHeightAtPoint,point.y);
}