线槽路径最优化算法(二)

接线板创建

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];
        }

猜你喜欢

转载自blog.csdn.net/m0_37965883/article/details/107509252