예제 #1
0
        private XVector3 BisectionSearch(XVector3 origin, XVector3 end, float min, float max)
        {
            float    mid    = (min + max) / 2;
            XVector3 newEnd = end + mid * XVector3.Normalize(end - origin);
            float    minDot = float.MaxValue;

            for (int i = 0; i < _verts.Length; i++)
            {
                float dot = XVector3.Dot(XVector3.Normalize(origin - newEnd), XVector3.Normalize(_verts[i] - newEnd));
                if (dot < -_Epsilon)
                {
                    return(BisectionSearch(origin, end, mid, max));
                }
                if (minDot > dot)
                {
                    minDot = dot;
                }
            }

            if (minDot > _Epsilon)
            {
                return(BisectionSearch(origin, end, min, mid));
            }
            return(newEnd);
        }
예제 #2
0
        private void GetReferencePoint()
        {
            bool  assigned = false;
            float min      = float.MaxValue;

            var ji = XVector3.Normalize(_verts[0] - _verts[1]);
            var jk = XVector3.Normalize(_verts[2] - _verts[1]);
            var kl = XVector3.Normalize(_verts[3] - _verts[2]);
            var il = XVector3.Normalize(_verts[3] - _verts[0]);
            var ij = -ji;
            var kj = -jk;
            var lk = -kl;
            var li = -il;

            float[] dots = { XVector3.Dot(ij, il), XVector3.Dot(ji, jk),
                             XVector3.Dot(kj, kl), XVector3.Dot(lk, li) };

            for (int n = 0; n < dots.Length; n++)
            {
                if (dots[n] > -_Epsilon && min > dots[n] && (dots[(n + 3) % dots.Length] > -_Epsilon ||
                                                             dots[(n + 1) % dots.Length] > -_Epsilon))
                {
                    assigned = true;
                    Start    = _verts[n];
                    Corner   = _verts[(n + 1) % dots.Length];
                    min      = dots[n];
                }
            }
            if (!assigned)
            {
                Start  = _verts[0];
                Corner = _verts[1];
            }
        }
예제 #3
0
        public static float Dot(XVector3 a, XVector3 b)
        {
            float dot = 0;

            dot += a.x * b.x;
            dot += a.y * b.y;
            dot += a.z * b.z;
            return(dot);
        }
예제 #4
0
        private bool CheckVolume()
        {
            float volume = XVector3.Distance(_verts[0], _verts[1]);

            volume *= XVector3.Distance(_verts[1], _verts[2]);

            XVector3 high = GetPoint(Directions.Up);
            XVector3 low  = GetPoint(Directions.Down);

            volume *= high.y - low.y;

            TooSmall = volume < 70;
            return(TooSmall);
        }
예제 #5
0
        private int ExponentialSearch(XVector3 origin, XVector3 end, int step = -1)
        {
            var newEnd = end + Exp(step) * XVector3.Normalize(end - origin);

            for (int i = 0; i < _verts.Length; i++)
            {
                float dot = XVector3.Dot(XVector3.Normalize(origin - newEnd), XVector3.Normalize(_verts[i] - newEnd));
                if (dot < 0)
                {
                    return(ExponentialSearch(origin, end, step + 1));
                }
            }
            return(step);
        }
예제 #6
0
        private XVector3 GetFurthestVertFrom(XVector3 o)
        {
            MaxHeap <XVector3> sorter = new MaxHeap <XVector3>((XVector3 a, XVector3 b) =>
            {
                return((XVector3.Distance(o, a) <= XVector3.Distance(o, b)) ? -1 : 1);
            });

            foreach (XVector3 vert in _verts)
            {
                sorter.Add(vert);
            }

            return(sorter.Remove());
        }
예제 #7
0
        private float MinDistanceBetweenAdjacentVerts()
        {
            float min = float.MaxValue;

            for (int i = 0; i < _verts.Length - 1; i++)
            {
                for (int j = i + 1; j < _verts.Length; j++)
                {
                    float a = XVector3.Distance(_verts[i], _verts[j]);
                    if (min > a)
                    {
                        min = a;
                    }
                }
            }
            return(min);
        }
예제 #8
0
 public BoxIdentifier(IClosestPoint point)
 {
     unity   = point;
     _Centre = new XVector3(point.GetCentre());
     try
     {
         GetVertices();
         if (!CheckVolume())
         {
             GetDimensions();
         }
     }
     catch
     {
         GetAltVertices();
         if (!CheckVolume())
         {
             GetDimensions();
         }
     }
 }
예제 #9
0
        private void GetDimensions()
        {
            int step = ExponentialSearch(Start, Corner);

            if (step > 0)
            {
                Corner = BisectionSearch(Start, Corner, Exp(step - 1), Exp(step));
            }
            Length = XVector3.Distance(Start, Corner);
            //unity.Message(Start +" " + Corner);
            End = Start - Corner;
            End = new XVector3(-End.z, End.y, End.x);
            End = Corner + End.normalized;// * MinDistanceBetweenAdjacentVerts();

            step = ExponentialSearch(Corner, End);

            if (step > 0)
            {
                End = BisectionSearch(Corner, End, Exp(step - 1), Exp(step));
            }
            Width = XVector3.Distance(Corner, End);
            /* refPoint -> lineEnd -> lineEnd2 ALWAYS clockwise; vertices[i++] ALWAYS clockwise */
        }
예제 #10
0
        public static XVector3 Normalize(XVector3 a)
        {
            var o = new XVector3();

            return(a / Distance(o, a));
        }
예제 #11
0
        public static XVector3 operator -(XVector3 b)
        {
            XVector3 a = new XVector3(-b.x, -b.y, -b.z);

            return(a);
        }
예제 #12
0
        public static XVector3 operator /(XVector3 b, float divisor)
        {
            XVector3 a = new XVector3(b.x / divisor, b.y / divisor, b.z / divisor);

            return(a);
        }
예제 #13
0
        public static XVector3 operator *(float multiplier, XVector3 b)
        {
            XVector3 a = new XVector3(b.x * multiplier, b.y * multiplier, b.z * multiplier);

            return(a);
        }
예제 #14
0
        public static XVector3 operator -(XVector3 b, XVector3 c)
        {
            XVector3 a = new XVector3(b.x - c.x, b.y - c.y, b.z - c.z);

            return(a);
        }
예제 #15
0
        public static XVector3 operator +(XVector3 b, XVector3 c)
        {
            XVector3 a = new XVector3(b.x + c.x, b.y + c.y, b.z + c.z);

            return(a);
        }
예제 #16
0
        public static float Distance(XVector3 o, XVector3 a)
        {
            XVector3 line = a - o;

            return((float)Math.Sqrt(line.x * line.x + line.y * line.y + line.z * line.z));
        }