private void GetClosestNeighborsInRange(List <KDShape> closeShapes, KDShape shape, float sqrdistance) { if (!IsLeaf()) { float currentPos = shape.GetPosition(dimensionalDepth); bool smaller = currentPos <= median; (smaller ? smallerBranch : biggerBranch).GetClosestNeighborsInRange(closeShapes, shape, sqrdistance); if (shape.DistanceToWall(median, dimensionalDepth) >= sqrdistance) { return; } (smaller ? biggerBranch : smallerBranch).GetClosestNeighborsInRange(closeShapes, shape, sqrdistance); } else { for (int i = 0; i < shapes.Count; i++) { if (shapes[i] != shape) { float dis = shape.GetDistance(shapes[i]); if (dis < sqrdistance) { closeShapes.Add(shapes[i]); } } } } }
void Update() { KDShape shape = CollisionShapesManager.Tree.GetClosestNeighbor(square); if (shape != null) { if (square.GetDistance(shape) <= 0) { renderer.color = Color.white; } else { renderer.color = Color.black; } } float speed = 1f * Time.deltaTime; Vector3 newPos = transform.position + new Vector3(Mathf.Cos(dir), Mathf.Sin(dir)) * speed; Vector3 pixelNewPos = Camera.main.WorldToScreenPoint(newPos); if (pixelNewPos.x < 0 || pixelNewPos.x >= Screen.width || pixelNewPos.y < 0 || pixelNewPos.y >= Screen.height) { dir = Random.Range(0, 360f); } else { transform.position = newPos; } square.x = transform.position.x; square.y = transform.position.y; }
public override float GetDistance(KDShape another) { if (another.MaxDimensions < MaxDimensions) { float _x = x - another.GetPosition(0); return(_x * _x); } else { return(new Vector2(x - another.GetPosition(0), y - another.GetPosition(1)).sqrMagnitude); } }
/// <summary> /// Return the closest shape to "shape". /// </summary> /// <param name="shape">the shape.</param> /// <returns></returns> public KDShape GetClosestNeighbor(KDShape shape) { KDShape closeShape = null; float closeDistance = float.NaN; if (!IsLeaf()) { float currentPos = shape.GetPosition(dimensionalDepth); bool smaller = currentPos <= median; closeShape = (smaller ? smallerBranch : biggerBranch).GetClosestNeighbor(shape, ref closeDistance); if (closeShape != null) { if (shape.DistanceToWall(median, dimensionalDepth) >= closeDistance) { return(closeShape); } } KDShape otherClose = (smaller ? biggerBranch : smallerBranch).GetClosestNeighbor(shape, ref closeDistance); if (otherClose != null) { closeShape = otherClose; } } else { for (int i = 0; i < shapes.Count; i++) { if (shapes[i] != shape) { if (float.IsNaN(closeDistance)) { closeDistance = shape.GetDistance(shapes[i]); closeShape = shapes[i]; } else { float dis = shape.GetDistance(shapes[i]); if (dis < closeDistance) { closeDistance = dis; closeShape = shapes[i]; } } } } } return(closeShape); }
public override int CompareTo(KDShape other, int dimension) { if (dimension == 0) { return((int)Mathf.Sign(x - other.GetPosition(dimension))); } else if (dimension == 1) { return((int)Mathf.Sign(y - other.GetPosition(dimension))); } else { throw new Exception("There is not more dimensions to get"); } }
public override float GetDistance(KDShape another) { if (another.GetType() == typeof(Square)) { Square square = (Square)another; Vector2 squarePoint = new Vector2(Mathf.Clamp(x, square.x - square.scaleX, square.x + square.scaleX), Mathf.Clamp(y, square.y - square.scaleY, square.y + square.scaleY)); Vector2 q = new Vector2(Mathf.Abs(squarePoint.x - x) - scaleX, Mathf.Abs(squarePoint.y - y) - scaleY); float maxQX = Mathf.Max(q.x, 0); float maxQY = Mathf.Max(q.y, 0); float dis = Mathf.Sqrt(maxQX * maxQX + maxQY * maxQY) + Mathf.Min(Mathf.Max(q.x, q.y), 0); return(dis); } return(0); }
/// <summary> /// Adds a shape to the list of shapes. /// </summary> /// <param name="shape">the shape. NOTE its position must be uniqe were there arent 2 points or more ar in the same position exactly.</param> public void AddShape(KDShape shape) { if (!IsLeaf()) { (shape.GetPosition(dimensionalDepth) <= median ? smallerBranch : biggerBranch).AddShape(shape); } else { if (!shapes.Any(x => x.IsEqualPosition(shape))) { shapes.Add(shape); if (shapes.Count > limit) { Split(); } } } }
public override bool IsEqualPosition(KDShape another) { return(x == another.GetPosition(0) && y == another.GetPosition(1)); }
/// <summary> /// Returns if this shape's position is exactly the same with "another" shape. /// </summary> /// <param name="another">the other shape to compare position with.</param> /// <returns></returns> public abstract bool IsEqualPosition(KDShape another);
/// <summary> /// Returns signed number to know who is bigger in certain dimension. /// <br>signed number: Should be either -1, 0 or 1. So -1 mean this shape is smaller than "another" shape</br> /// <br>Most of the cases the function would be: Mathf.Sign(GetPosition(dimension) - another.GetPosition(dimension))</br> /// </summary> /// <param name="another">the other shape to compare.</param> /// <param name="dimension">the certain dimension to compate.</param> /// <returns></returns> public abstract int CompareTo(KDShape another, int dimension);
/// <summary> /// Return the distance from this shape to "another" shape /// <br>NOTE: This is seperate function so you can use area shapes distance functions.</br> /// </summary> /// <param name="another">The other shape to calculate distance from.</param> /// <returns></returns> public abstract float GetDistance(KDShape another);
public override int CompareTo(KDShape another, int dimension) { return((int)Mathf.Sign(GetPosition(dimension) - another.GetPosition(dimension))); }