Example #1
0
 private static double _getSquaredDistanceTo(T value, double x, double y, double defaultValue = double.PositiveInfinity)
 {
     return(value == null
         ? defaultValue
         : Geom.SumSqr(value.X - x, value.Y - y));
 }
Example #2
0
        private void _findAllNearby(Node node, double left, double top, double right, double bottom)
        {
            if (node.Value != null)
            {
                if (_getSquaredDistanceTo(node.Value) <= _squaredDistanceE)
                {
                    _values.Add(node.Value);
                }
                return;
            }

            if (!node.HasValueBelow)
            {
                return;
            }

            var centerX = (left + right) / 2.0D;
            var centerY = (top + bottom) / 2.0D;

            if (_x < centerX)
            {
                if (_y < centerY)
                {
                    _findAllNearby(node.LeftTop, left, top, centerX, centerY);

                    if (_squaredDistanceE >= Geom.Sqr(centerX - _x))
                    {
                        _findAllNearby(node.RightTop, centerX, top, right, centerY);
                    }

                    if (_squaredDistanceE >= Geom.Sqr(centerY - _y))
                    {
                        _findAllNearby(node.LeftBottom, left, centerY, centerX, bottom);
                    }

                    if (_squaredDistanceE >= Geom.SumSqr(centerX - _x, centerY - _y))
                    {
                        _findAllNearby(node.RightBottom, centerX, centerY, right, bottom);
                    }
                }
                else
                {
                    _findAllNearby(node.LeftBottom, left, centerY, centerX, bottom);

                    if (_squaredDistanceE >= Geom.Sqr(centerX - _x))
                    {
                        _findAllNearby(node.RightBottom, centerX, centerY, right, bottom);
                    }

                    if (_squaredDistanceE > Geom.Sqr(_y - centerY))
                    {
                        _findAllNearby(node.LeftTop, left, top, centerX, centerY);
                    }

                    if (_squaredDistanceE >= Geom.SumSqr(centerX - _x, _y - centerY))
                    {
                        _findAllNearby(node.RightTop, centerX, top, right, centerY);
                    }
                }
            }
            else
            {
                if (_y < centerY)
                {
                    _findAllNearby(node.RightTop, centerX, top, right, centerY);

                    if (_squaredDistanceE > Geom.Sqr(_x - centerX))
                    {
                        _findAllNearby(node.LeftTop, left, top, centerX, centerY);
                    }

                    if (_squaredDistanceE >= Geom.Sqr(centerY - _y))
                    {
                        _findAllNearby(node.RightBottom, centerX, centerY, right, bottom);
                    }

                    if (_squaredDistanceE >= Geom.SumSqr(_x - centerX, centerY - _y))
                    {
                        _findAllNearby(node.LeftBottom, left, centerY, centerX, bottom);
                    }
                }
                else
                {
                    _findAllNearby(node.RightBottom, centerX, centerY, right, bottom);

                    if (_squaredDistanceE > Geom.Sqr(_x - centerX))
                    {
                        _findAllNearby(node.LeftBottom, left, centerY, centerX, bottom);
                    }

                    if (_squaredDistanceE > Geom.Sqr(_y - centerY))
                    {
                        _findAllNearby(node.RightTop, centerX, top, right, centerY);
                    }

                    if (_squaredDistanceE > Geom.SumSqr(_x - centerX, _y - centerY))
                    {
                        _findAllNearby(node.LeftTop, left, top, centerX, centerY);
                    }
                }
            }
        }
Example #3
0
 private double _getSquaredDistanceTo(T value, double defaultValue = double.PositiveInfinity)
 {
     return(value == null || value.Id == _id
         ? defaultValue
         : Geom.SumSqr(value.X - _x, value.Y - _y));
 }
Example #4
0
        private T _findNearest(Node node, double left, double top, double right, double bottom)
        {
            if (node.Value != null)
            {
                if (_getSquaredDistanceTo(node.Value, _squaredDistance) <= _squaredDistanceE)
                {
                    return(node.Value);
                }
                return(null);
            }

            if (!node.HasValueBelow)
            {
                return(null);
            }

            var centerX = (left + right) / 2.0D;
            var centerY = (top + bottom) / 2.0D;

            if (_x < centerX)
            {
                if (_y < centerY)
                {
                    var nearestValue           = _findNearest(node.LeftTop, left, top, centerX, centerY);
                    var nearestSquaredDistance = _getSquaredDistanceTo(nearestValue, _squaredDistance);

                    if (nearestSquaredDistance + _epsilon >= Geom.Sqr(centerX - _x))
                    {
                        var otherValue           = _findNearest(node.RightTop, centerX, top, right, centerY);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue           = otherValue;
                            nearestSquaredDistance = otherSquaredDistance;
                        }
                    }

                    if (nearestSquaredDistance + _epsilon >= Geom.Sqr(centerY - _y))
                    {
                        var otherValue           = _findNearest(node.LeftBottom, left, centerY, centerX, bottom);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue           = otherValue;
                            nearestSquaredDistance = otherSquaredDistance;
                        }
                    }

                    if (nearestSquaredDistance + _epsilon >= Geom.SumSqr(centerX - _x, centerY - _y))
                    {
                        var otherValue           = _findNearest(node.RightBottom, centerX, centerY, right, bottom);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue = otherValue;
                        }
                    }

                    return(nearestValue);
                }
                else
                {
                    var nearestValue           = _findNearest(node.LeftBottom, left, centerY, centerX, bottom);
                    var nearestSquaredDistance = _getSquaredDistanceTo(nearestValue, _squaredDistance);

                    if (nearestSquaredDistance + _epsilon >= Geom.Sqr(centerX - _x))
                    {
                        var otherValue           = _findNearest(node.RightBottom, centerX, centerY, right, bottom);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _x, _y, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue           = otherValue;
                            nearestSquaredDistance = otherSquaredDistance;
                        }
                    }

                    if (nearestSquaredDistance + _epsilon > Geom.Sqr(_y - centerY))
                    {
                        var otherValue           = _findNearest(node.LeftTop, left, top, centerX, centerY);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue           = otherValue;
                            nearestSquaredDistance = otherSquaredDistance;
                        }
                    }

                    if (nearestSquaredDistance + _epsilon >= Geom.SumSqr(centerX - _x, _y - centerY))
                    {
                        var otherValue           = _findNearest(node.RightTop, centerX, top, right, centerY);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue = otherValue;
                        }
                    }

                    return(nearestValue);
                }
            }
            else
            {
                if (_y < centerY)
                {
                    var nearestValue           = _findNearest(node.RightTop, centerX, top, right, centerY);
                    var nearestSquaredDistance = _getSquaredDistanceTo(nearestValue, _squaredDistance);

                    if (nearestSquaredDistance + _epsilon > Geom.Sqr(_x - centerX))
                    {
                        var otherValue           = _findNearest(node.LeftTop, left, top, centerX, centerY);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue           = otherValue;
                            nearestSquaredDistance = otherSquaredDistance;
                        }
                    }

                    if (nearestSquaredDistance + _epsilon >= Geom.Sqr(centerY - _y))
                    {
                        var otherValue           = _findNearest(node.RightBottom, centerX, centerY, right, bottom);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue           = otherValue;
                            nearestSquaredDistance = otherSquaredDistance;
                        }
                    }

                    if (nearestSquaredDistance + _epsilon >= Geom.SumSqr(_x - centerX, centerY - _y))
                    {
                        var otherValue           = _findNearest(node.LeftBottom, left, centerY, centerX, bottom);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue = otherValue;
                        }
                    }

                    return(nearestValue);
                }
                else
                {
                    var nearestValue           = _findNearest(node.RightBottom, centerX, centerY, right, bottom);
                    var nearestSquaredDistance = _getSquaredDistanceTo(nearestValue, _squaredDistance);

                    if (nearestSquaredDistance + _epsilon > Geom.Sqr(_x - centerX))
                    {
                        var otherValue           = _findNearest(node.LeftBottom, left, centerY, centerX, bottom);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue           = otherValue;
                            nearestSquaredDistance = otherSquaredDistance;
                        }
                    }

                    if (nearestSquaredDistance + _epsilon > Geom.Sqr(_y - centerY))
                    {
                        var otherValue           = _findNearest(node.RightTop, centerX, top, right, centerY);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue           = otherValue;
                            nearestSquaredDistance = otherSquaredDistance;
                        }
                    }

                    if (nearestSquaredDistance + _epsilon > Geom.SumSqr(_x - centerX, _y - centerY))
                    {
                        var otherValue           = _findNearest(node.LeftTop, left, top, centerX, centerY);
                        var otherSquaredDistance = _getSquaredDistanceTo(otherValue, _squaredDistance);

                        if (otherSquaredDistance < nearestSquaredDistance)
                        {
                            nearestValue = otherValue;
                        }
                    }

                    return(nearestValue);
                }
            }
        }