Exemple #1
0
        /// <summary>
        /// Check if the vertex is "visible" from the face.
        /// The vertex is "over face" if the return value is > Constants.PlaneDistanceTolerance.
        /// </summary>
        /// <param name="v"></param>
        /// <param name="f"></param>
        /// <returns>The vertex is "over face" if the result is positive.</returns>
        public double GetVertexDistance(int v, ConvexFaceInternal f)
        {
            var normal = f.Normal;
            var x      = v * _dimension;

            return(f.Offset + normal.Select((t, i) => t * _positionData[x + i]).Sum());
        }
        /// <summary>
        /// Reallocate the face pool, including the AffectedFaceFlags
        /// </summary>
        private void ReallocateFacePool()
        {
            var newPool = new ConvexFaceInternal[2 * _facePoolCapacity];
            var newTags = new bool[2 * _facePoolCapacity];

            Array.Copy(_facePool, newPool, _facePoolCapacity);
            Buffer.BlockCopy(_hull.AffectedFaceFlags, 0, newTags, 0, _facePoolCapacity * sizeof(bool));
            _facePoolCapacity       = 2 * _facePoolCapacity;
            _hull.FacePool          = newPool;
            _facePool               = newPool;
            _hull.AffectedFaceFlags = newTags;
        }
        /// <summary>
        /// Create a new face and put it in the pool.
        /// </summary>
        /// <returns></returns>
        private int CreateFace()
        {
            var index = _facePoolSize;
            var face  = new ConvexFaceInternal(_dimension, index, GetVertexBuffer());

            _facePoolSize++;
            if (_facePoolSize > _facePoolCapacity)
            {
                ReallocateFacePool();
            }
            _facePool[index] = face;
            return(index);
        }
Exemple #4
0
        /// <summary>
        /// Computes the volume of an n-dimensional simplex.
        /// Buffer needs to be array of shape Dimension x Dimension.
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="vertices"></param>
        /// <param name="buffer">Helper for the calculation to avoid unnecessary allocations.</param>
        /// <returns></returns>
        public static double GetSimplexVolume(ConvexFaceInternal cell, IList <IVertex> vertices, SimplexVolumeBuffer buffer)
        {
            var xs    = cell.Vertices;
            var pivot = vertices[xs[0]].Position;
            var data  = buffer.Data;
            var dim   = buffer.Dimension;
            var f     = 1.0;

            for (var i = 1; i < xs.Length; i++)
            {
                f *= i + 1;
                var point = vertices[xs[i]].Position;
                for (var j = 0; j < point.Length; j++)
                {
                    data[j * dim + i - 1] = point[j] - pivot[j];
                }
            }

            return(Math.Abs(DeterminantDestructive(buffer)) / f);
        }
Exemple #5
0
        /// <summary>
        /// Calculates the normal and offset of the hyper-plane given by the face's vertices.
        /// </summary>
        /// <param name="face"></param>
        /// <param name="center"></param>
        /// <returns></returns>
        public bool CalculateFacePlane(ConvexFaceInternal face, double[] center)
        {
            var vertices = face.Vertices;
            var normal   = face.Normal;

            FindNormalVector(vertices, normal);

            if (double.IsNaN(normal[0]))
            {
                return(false);
            }

            var offset         = 0.0;
            var centerDistance = 0.0;
            var fi             = vertices[0] * _dimension;

            for (var i = 0; i < _dimension; i++)
            {
                var n = normal[i];
                offset         += n * _positionData[fi + i];
                centerDistance += n * center[i];
            }
            face.Offset     = -offset;
            centerDistance -= offset;

            if (centerDistance > 0)
            {
                for (var i = 0; i < _dimension; i++)
                {
                    normal[i] = -normal[i];
                }
                face.Offset          = offset;
                face.IsNormalFlipped = true;
            }
            else
            {
                face.IsNormalFlipped = false;
            }

            return(true);
        }
Exemple #6
0
        /// <summary>
        /// Updates the connector.
        /// </summary>
        /// <param name="face"></param>
        /// <param name="edgeIndex"></param>
        /// <param name="dim"></param>
        public void Update(ConvexFaceInternal face, int edgeIndex, int dim)
        {
            Face      = face;
            EdgeIndex = edgeIndex;

            uint hashCode = 23;

            unchecked {
                var vs = face.Vertices;
                int i, c = 0;
                for (i = 0; i < edgeIndex; i++)
                {
                    Vertices[c++] = vs[i];
                    hashCode     += 31 * hashCode + (uint)vs[i];
                }
                for (i = edgeIndex + 1; i < vs.Length; i++)
                {
                    Vertices[c++] = vs[i];
                    hashCode     += 31 * hashCode + (uint)vs[i];
                }
            }

            HashCode = hashCode;
        }