获取钢板轮廓点集

  生成骨骼三维模型后,点击钢板创建进入另一个Unity场景。在该场景中,我们可以自由旋转缩放平移生成的骨骼模型。本章将重点描述钢板模型采样点的生成。钢板创建场景的控制类主要有3个:

  • BoardTunning.cs (菜单栏)
  • CreateBoardController.cs (核心流程控制器)
  • CutPathController.cs (钢板轮廓点处理)

  在创建钢板前,需要固定视角,点击左上角的Lock View按钮固定视角,便可以在骨骼模型上单击鼠标进行描点。

  采样点的获取使用了Unity的射线机制,通过从屏幕向模型发出一条射线来检测碰撞点,具体代码位于CreateBoardContorller.cs中,单击鼠标触发:

public void AddContourPoint()
{
    if (state != SystemState.InputContour || isMouseOnUI()) return;

    if (!CheckLock()) return;

    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);  // 从屏幕发出射线
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit))  // 碰撞检测
    {
        if (cutPathController.AddPoint(Input.mousePosition)) // 添加控制点
        {
            if (cutPathController.isContourClose)  // 控制点闭合
            {
                ContourClose();
            }
        }
        else
        {    // 无法闭合
            MessageBox.Show("Contour Edge Intersect!", 1);
        }
    }
}

  控制点数据的处理位于CutPathController.cs中,添加控制点前需要判断合法性,如果加入的新控制点和以往的控制点的连线相交,那么该控制点是不被允许的。同时还要判断新控制点是否接近第一个控制点,如果是,那么曲线闭合,采样点过程结束:

public bool AddPoint(Vector2 point)
{
  if (listAnchorPosition.Count > 2)
  {
      int startIndex = 0;
      if (IsCloseToFirstPoint(point))
      {    // 曲线闭合不需要检查第1个点和第2个点的连线的相交情况
          startIndex = 1;
          isContourClose = true;
      }
      int count = listAnchorPosition.Count;
      for (int i = startIndex; i < count - 2; i++)
      {    // 检查连线相交
          Vector2 p0 = listAnchorPosition[i];
          Vector2 p1 = listAnchorPosition[i + 1];
          Vector2 p2 = listAnchorPosition[count - 1];
          if (Calculator.IsIntersection(p0, p1, p2, point))
          {    // 新控制点连线不能和原连线相交
              isContourClose = false;
              return false;
          }
      }
  }
  else if (listAnchorPosition.Count == 2)
  {    // 第3个点不能和第1个点闭合
      if (IsCloseToFirstPoint(point))
      {
          isContourClose = true;
          return false;
      }
  }

  if (!isContourClose)
  {    // 添加新的控制点
      listAnchorPosition.Add(point);
  }

  UpateVectorLine(listAnchorPosition, false);  // 更新点间连线
  return true;
}

  线段相交检测算法由工具类Calculator负责,Calculator专门计算线段连线相交情况,具体代码不再给出。

  当曲线闭合后,对采样点连线进行贝塞尔平滑处理,处理的方法和前面提到的方法相同。

  相关代码位于CutPathController.cs

public void TurnToCurve(float curvature)
{
    this.curvature = curvature;  // 平滑程度
    listCurvePosition = Bezier.CreateCurveWithDistance(listAnchorPosition, curvature, 10f);
    Polygon.Clear();
    for (int i = 0; i < listCurvePosition.Count; i++)
    {    // Polygon记录轮廓点
        Polygon.AddPoint(listCurvePosition[i]);
    }
    UpateVectorLine(listCurvePosition, true);  // 更新点间连线,这里贝塞尔曲线采样点不会显示
}

  完成上述步骤,我们已有的数据是钢板面片的轮廓点集,接下来就可以进行钢板模型的创建了。

results matching ""

    No results matching ""