예제 #1
0
    bool IsOriented(Vector3 normal, PointNormal normal0, PointNormal normal1, PointNormal normal2)
    {
        int count = 0;

        count = normal.NormalDot(normal0) < 0 ? count + 1 : count;
        count = normal.NormalDot(normal1) < 0 ? count + 1 : count;
        count = normal.NormalDot(normal2) < 0 ? count + 1 : count;
        return(count <= 1);
    }
 public static extern void std_vector_pointnormal_insert(IntPtr ptr, IntPtr idx, PointNormal value);
 public static extern void std_vector_pointnormal_add(IntPtr ptr, PointNormal value);
 public static extern void std_vector_pointnormal_at(IntPtr ptr, UIntPtr idx, ref PointNormal value);
예제 #5
0
    internal Tuple <int, Triangle> Pivot(Edge e)
    {
        Tuple <PointNormal, int> v0 = e.First;
        Tuple <PointNormal, int> v1 = e.Second;
        Tuple <PointNormal, int> op = e.OppositeVertex;

        //Vector3 diff1 = 100 * (v0.Item1.AsVector3() - middle);
        //Vector3 diff2 = 100 * (e.BallCenter.AsVector3() - middle);

        //Vector3 y = Vector3.Cross(diff1, diff2).normalized;
        //Vector3 normal = Vector3.Cross(diff2, y).normalized;
        Vector3    normal = (v0.Item1 - e.MiddlePoint).normalized;
        HyperPlane plane  = new HyperPlane(normal, e.MiddlePoint);

        Vector3 zeroAngle = op.Item1 - e.MiddlePoint;

        zeroAngle = plane.Projection(zeroAngle).normalized;

        float currentAngle           = Mathf.PI;
        Tuple <int, Triangle> output = null;

        int[] indices = GetNeighbors(e.MiddlePoint, ballRadius * 2).ToArray();
        for (int t = 0; t < indices.Length; t++)
        {
            int index = indices[t];
            if (v0.Item2 == index || v1.Item2 == index || op.Item2 == index)
            {
                continue;
            }

            PointNormal point = cloud[index];
            if (plane.AbsDistance(point) <= ballRadius)
            {
                Vector3 center;
                if (GetBallCenter(v0.Item2, v1.Item2, index, out center, out _))
                {
                    List <int> neighborhood = GetNeighbors(center, ballRadius);
                    if (!isEmpty(neighborhood, v0.Item2, v1.Item2, index, center))
                    {
                        continue;
                    }

                    Vector3 Vij        = v1.Item1.AsVector3() - v0.Item1.AsVector3();
                    Vector3 Vik        = point - v0.Item1.AsVector3();
                    Vector3 faceNormal = Vector3.Cross(Vik, Vij).normalized;

                    if (!IsOriented(faceNormal, v0.Item1, v1.Item1, cloud[index]))
                    {
                        continue;
                    }

                    float cosAngle = zeroAngle.Dot(plane.Projection(center).normalized);
                    if (Mathf.Abs(cosAngle) > 1.0f)
                    {
                        cosAngle = Mathf.Sign(cosAngle);
                    }

                    float angle = Mathf.Acos(cosAngle);

                    if (output == null || currentAngle > angle)
                    {
                        currentAngle = angle;
                        output       = new Tuple <int, Triangle>(index, new Triangle(v0.Item1, cloud[index], v1.Item1, v0.Item2, index, v1.Item2, center, ballRadius));
                    }
                }
            }
        }

        return(output);
    }