接线板创建
1.吧接线板分成一个个长方形,长为线的走向,宽为线束的排列;
2.在每个接线板上生产若干个节点,人为的定义其中的拐点(起点和终点也是拐点)
3.代码很简单,就不说明了
//生产节点
private void SpawnConnectPoints()
{
//参数计算
switch (lengthAxis)
{
case "x":
lengthDir = transform.right.normalized;
break;
case "y":
lengthDir = transform.up.normalized;
break;
case "z":
lengthDir = transform.forward.normalized;
break;
}
switch (widthAxis)
{
case "x":
widthDir = transform.right.normalized;
break;
case "y":
widthDir = transform.up.normalized;
break;
case "z":
widthDir = transform.forward.normalized;
break;
}
widthSpace = (width - 2 * widthMargin) / (widthNum - 1);
//创建自定义点父对象
customPointParent = new GameObject("customPointParent").transform;
customPointParent.localScale = Vector3.one;
customPointParent.SetParent(transform);
customPointParent.localPosition = Vector3.zero;
customPointParent.localRotation = Quaternion.identity;
//生产原点
originalPoint = new GameObject("originalPoint").transform;
originalPoint.SetParent(transform);
originalPoint.position = transform.position - lengthDir * (length / 2) - widthDir * (width / 2) +
widthDir * widthMargin;
//生产参考拐点
foreach (var bpf in breakPointsFloats)
{
var newRefT = new GameObject("refPoint").transform;
newRefT.SetParent(transform);
newRefT.position = transform.position + lengthDir * bpf - widthDir * (width / 2) +
widthDir * widthMargin;
breakPointRefs.Add(newRefT);
}
//生产接点
int count = (int) ((length - lengthMargin) / lengthSpace) + 1;
for (int i = 0; i < count; i++)
{
var newConT = new GameObject("connPoint").transform;
newConT.position = originalPoint.position + lengthDir * lengthMargin + i * lengthSpace * lengthDir;
newConT.SetParent(transform);
connectPoints.Add(newConT);
}
startConnPoint = connectPoints[0];
endConnPoint = connectPoints[connectPoints.Count - 1];
//寻找拐点
if (isAllBreak)
{
breakPoints = connectPoints;
}
else
{
AddBreakPoint(startConnPoint);
AddBreakPoint(endConnPoint);
foreach (var bpRef in breakPointRefs)
{
var ref2startDis = Vector3.Distance(startConnPoint.position, bpRef.position);
AddBreakPoint(connectPoints[GetCloseIndex(ref2startDis)]);
}
}
}
开始第一步,查找连线起终点两处,向其接线前方分别查找最近的节点
1.大概逻辑:各个接线板,接线点最近的节点,一般是用接线点向接线板的节点直线做垂线,得到的垂足,垂足附近的节点即最近的点,但考虑到还要再接线点正前方,所以还要用接线点正前方矢量的法线平面和节点直线做交点,比较垂足和交点,判断垂足是否满足;
2.垂足坐标的求解
/// <summary>
/// 获取垂足坐标
/// </summary>
/// <param name="startV">起始点</param>
/// <param name="endV">终点</param>
/// <param name="refV">求解点</param>
/// <returns>返回求解点在起始终点直线的垂足坐标</returns>
private Vector3 GetPedalV3(Vector3 startV, Vector3 endV, Vector3 refV)
{
var normalDirV = (endV - startV).normalized;
var rat = Vector3.Dot(refV, normalDirV) - Vector3.Dot(startV, normalDirV);
return startV + normalDirV * rat;
}
3.交点坐标求解
//获得点正前方法向平面和start2end的交点
private Vector3 GetForwardNorIntersectV3(Transform pointT)
{
var forwardV = pointT.forward;
var normalDirV = (endConnPoint.position - startConnPoint.position).normalized;
var rat = Vector3.Dot(pointT.position - startConnPoint.position, forwardV) /
Vector3.Dot(normalDirV, forwardV);
return startConnPoint.position + normalDirV * rat;
}
4.获取节点代码
//获取最近的节点
public Transform SearchClosestCP(Transform pointT)
{
if (isSpec) return connectPoints[0];
pedalV = GetPedalV3(startConnPoint.position, endConnPoint.position,
pointT.position);
var pedal2start = startConnPoint.position - pedalV;
var pedal2end = endConnPoint.position - pedalV;
if (Math.Abs(Vector3.Angle(pedal2start, pedal2end) - 180) < 1f)
{
var projectionDis = Math.Abs(Vector3.Dot(pedal2start, lengthDir)); //求投影
var index = GetCloseIndex((float) projectionDis);
Debug.LogWarning($"投影:{
projectionDis},对应点的索引:{
index}");
return connectPoints[index];
}
else
{
var startDis = Vector3.Distance(pointT.position, startConnPoint.position);
var endDis = Vector3.Distance(pointT.position, endConnPoint.position);
return startDis < endDis ? startConnPoint : endConnPoint;
}
}
//只在有部分点在起始点前面时调用
public Transform SearchForwardClosestCP(Transform pointT)
{
if (isSpec) return connectPoints[0];
var intersectV = GetForwardNorIntersectV3(pointT);
var intersect2start = startConnPoint.position - intersectV;
var projectionDis = Mathf.Abs(Vector3.Dot(intersect2start, lengthDir));
var index = GetCloseIndex((float) projectionDis);
return connectPoints[index];
}