Beispiel #1
0
        /// <summary>
        /// Creates reference points for triangulation.
        ///
        /// The first is guaranteed to be the origin, and the second will be the opposite corner and
        /// have "max" for each of its coordinate values, where max = (2^bits) - 1.
        /// After that, the patterns will be:
        ///    { max, 0, max, 0, max, 0, ... }
        ///    { max, max, 0, 0, max, max, 0, 0, ... }
        ///    { max, max, max, 0, 0, 0, max, max, max, 0, 0, 0, ... }
        ///    { max, max, max, max, 0, 0, 0, 0, max, max, max, max, 0, 0, 0, 0, ... }
        /// </summary>
        /// <returns>The reference points.</returns>
        /// <param name="dimensions">Number of Dimensions for each point.</param>
        /// <param name="bits">Bits per coordinate.</param>
        /// <param name="numTriangulationPoints">Number of triangulation points to create.</param>
        private static UnsignedPoint[] CreateReferencePoints(int dimensions, int bits, int numTriangulationPoints)
        {
            var tPoints = new UnsignedPoint[numTriangulationPoints];
            var max     = (uint)((1 << bits) - 1);

            // The origin
            tPoints[0] = new UnsignedPoint(new uint[dimensions]);
            // The corner opposite the origin.
            tPoints[1] = new UnsignedPoint(
                Enumerable.Range(0, dimensions).Select(i => max).ToArray()
                );
            foreach (var i in Enumerable.Range(2, numTriangulationPoints - 2))
            {
                var coordinates = new uint[dimensions];
                for (var iDim = 0; iDim < dimensions; iDim++)
                {
                    if ((iDim / (i - 1)) % 2 == 0)
                    {
                        coordinates[i] = max;
                    }
                }
                tPoints[i] = new UnsignedPoint(coordinates);
            }
            return(tPoints);
        }
Beispiel #2
0
        public Triangulator(UnsignedPoint point, int bits, int numTriangulationPoints = 10)
        {
            Key = LookupKey(point.Dimensions, bits, numTriangulationPoints);
            var refPoints = GetReferencePoints(point.Dimensions, bits, numTriangulationPoints);

            ReferenceSquareDistances = new long[numTriangulationPoints];
            ReferenceDistances       = new double[numTriangulationPoints];
            for (var iTri = 0; iTri < numTriangulationPoints; iTri++)
            {
                ReferenceSquareDistances[iTri] = point.Measure(refPoints[iTri]);
                ReferenceDistances[iTri]       = Math.Sqrt(ReferenceSquareDistances[iTri]);
            }
        }
Beispiel #3
0
        /// <summary>
        /// If the point is already a HilbertPoint, return it unchanged, otherwise create a new one
        /// that contains the same coordinates yet has a Hilbert index.
        /// </summary>
        /// <returns>A HilbertPoint.</returns>
        /// <param name="uPoint">U point.</param>
        /// <param name="bitsPerDimension">Bits per dimension.</param>
        /// <param name="useSameKey">If true and a new point is created, it will share the same key as the original.</param>
        public static HilbertPoint CastOrConvert(UnsignedPoint uPoint, int bitsPerDimension, bool useSameKey = false)
        {
            HilbertPoint hPoint = uPoint as HilbertPoint;

            if (hPoint == null || hPoint.BitsPerDimension != bitsPerDimension)
            {
                if (useSameKey)
                {
                    hPoint = new HilbertPoint(uPoint.Coordinates, bitsPerDimension, uPoint.MaxCoordinate, uPoint.SquareMagnitude, uPoint.UniqueId);
                }
                else
                {
                    hPoint = new HilbertPoint(uPoint.Coordinates, bitsPerDimension, uPoint.MaxCoordinate, uPoint.SquareMagnitude);
                }
            }
            return(hPoint);
        }
Beispiel #4
0
        /// <summary>
        /// Can Triangulation bypass the need to compute the ful distance?
        ///
        /// THis method is only used for testing.
        /// </summary>
        /// <param name="other">Other.</param>
        /// <param name="squareDistance">Square distance.</param>
        public bool Triangulatable(UnsignedPoint other, long squareDistance)
        {
            var hPoint = other as HilbertPoint;

            if (hPoint == null)
            {
                return(false);
            }
            if (Triangulation.ArePointsFartherForSure(hPoint.Triangulation, squareDistance))
            {
                return(true);
            }
            if (Triangulation.ArePointsNearerForSure(hPoint.Triangulation, squareDistance))
            {
                return(true);
            }
            return(false);
        }
Beispiel #5
0
        public override int SquareDistanceCompare(UnsignedPoint other, long squareDistance)
        {
            var hPoint = other as HilbertPoint;

            if (hPoint == null)
            {
                return(base.SquareDistanceCompare(other, squareDistance));
            }
            if (Triangulation.ArePointsFartherForSure(hPoint.Triangulation, squareDistance))
            {
                return(1);
            }
            if (Triangulation.ArePointsNearerForSure(hPoint.Triangulation, squareDistance))
            {
                return(-1);
            }
            return(Measure(other).CompareTo(squareDistance));
        }