示例#1
0
    public const float c_sameDistance = 0.0001f; //相近的距离 QuaickHull是0.00000001f

    public Vector3[] Build(Vector3[] _points, int _cutCount = c_cutCount)
    {
        int count  = (int)Mathf.Pow(2, _cutCount);
        int border = count - 1;

        EightPoint        ep     = FindFirstMaxMin(_points);
        Vector3           min    = new Vector3(ep.xMin, ep.yMin, ep.zMin);
        Vector3           max    = new Vector3(ep.xMax, ep.yMax, ep.zMax);
        Vector3           step   = (max - min) / count;
        List <Vector3Int> blocks = new List <Vector3Int>(count);
        Vector3Int        v3int  = Vector3Int.zero;

        foreach (var point in _points)
        {
            v3int.x = (int)Mathf.Clamp((point.x - min.x) / step.x, 0, border);
            v3int.y = (int)Mathf.Clamp((point.y - min.y) / step.y, 0, border);
            v3int.z = (int)Mathf.Clamp((point.z - min.z) / step.z, 0, border);

            bool canAdd = true;
            foreach (var block in blocks)
            {
                if (block.x == v3int.x && block.y == v3int.y && block.z == v3int.z)
                {
                    canAdd = false;
                    break;
                }
            }

            if (canAdd)
            {
                blocks.Add(v3int);
            }
        }

        Vector3[] result = new Vector3[blocks.Count * 8];
        Vector3   start  = Vector3.zero;

        for (int i = 0; i < blocks.Count; i++)
        {
            var block = blocks[i];
            start.x = min.x + block.x * step.x;
            start.y = min.y + block.y * step.y;
            start.z = min.z + block.z * step.z;
            ep.OnInit(start, step);
            ep.AddEightPoints(result, i * 8);
        }

        RemoveRepeatedPoint(result);
        return(result);
    }
示例#2
0
    /// <summary>
    /// 找到第一次最大小的点
    /// 如果是面片会自己加框
    /// </summary>
    /// <param name="points"></param>
    /// <returns></returns>
    public EightPoint FindFirstMaxMin(Vector3[] points)
    {
        EightPoint ep = new EightPoint();

        if (points.Length > 0)
        {
            ep.xMin = ep.xMax = points[0].x;
            ep.yMin = ep.yMax = points[0].y;
            ep.zMin = ep.zMax = points[0].z;
        }
        else
        {
            throw new Exception("Points Length is zero");
        }

        foreach (var point in points)
        {
            if (point.x < ep.xMin)
            {
                ep.xMin = point.x;
            }
            else if (point.x > ep.xMax)
            {
                ep.xMax = point.x;
            }

            if (point.y < ep.yMin)
            {
                ep.yMin = point.y;
            }
            else if (point.y > ep.yMax)
            {
                ep.yMax = point.y;
            }

            if (point.z < ep.zMin)
            {
                ep.zMin = point.z;
            }
            else if (point.z > ep.zMax)
            {
                ep.zMax = point.z;
            }
        }

        if (ep.xMax - ep.xMin < c_sameDistance)
        {
            ep.xMin -= c_sameDistance;
            ep.xMax += c_sameDistance;
        }

        if (ep.yMax - ep.yMin < c_sameDistance)
        {
            ep.yMin -= c_sameDistance;
            ep.yMax += c_sameDistance;
        }

        if (ep.zMax - ep.zMin < c_sameDistance)
        {
            ep.zMin -= c_sameDistance;
            ep.zMax += c_sameDistance;
        }

        return(ep);
    }