获取钢板轮廓点集
生成骨骼三维模型后,点击钢板创建
进入另一个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); // 更新点间连线,这里贝塞尔曲线采样点不会显示
}
完成上述步骤,我们已有的数据是钢板面片的轮廓点集,接下来就可以进行钢板模型的创建了。