private float getArea(SpatialKey a) { if (a.isNull()) { return 0; } float area = 1; for (int i = 0; i < dimensions; i++) { area *= a.max(i) - a.min(i); } return area; }
/** * Get the area increase by extending a to contain b. * * @param objA the bounding box * @param objB the object * @return the area */ public float getAreaIncrease(Object objA, Object objB) { SpatialKey b = (SpatialKey) objB; SpatialKey a = (SpatialKey) objA; if (a.isNull() || b.isNull()) { return 0; } float min = a.min(0); float max = a.max(0); float areaOld = max - min; min = Math.min(min, b.min(0)); max = Math.max(max, b.max(0)); float areaNew = max - min; for (int i = 1; i < dimensions; i++) { min = a.min(i); max = a.max(i); areaOld *= max - min; min = Math.min(min, b.min(i)); max = Math.max(max, b.max(i)); areaNew *= max - min; } return areaNew - areaOld; }
/** * Check whether a is completely inside b and does not touch the * given bound. * * @param objA the object to check * @param objB the bounds * @return true if a is completely inside b */ public boolean isInside(Object objA, Object objB) { SpatialKey a = (SpatialKey) objA; SpatialKey b = (SpatialKey) objB; if (a.isNull() || b.isNull()) { return false; } for (int i = 0; i < dimensions; i++) { if (a.min(i) <= b.min(i) || a.max(i) >= b.max(i)) { return false; } } return true; }
/** * Check whether the two objects overlap. * * @param objA the first object * @param objB the second object * @return true if they overlap */ public boolean isOverlap(Object objA, Object objB) { SpatialKey a = (SpatialKey) objA; SpatialKey b = (SpatialKey) objB; if (a.isNull() || b.isNull()) { return false; } for (int i = 0; i < dimensions; i++) { if (a.max(i) < b.min(i) || a.min(i) > b.max(i)) { return false; } } return true; }
/** * Check whether a contains b. * * @param objA the bounding box * @param objB the object * @return the area */ public boolean contains(Object objA, Object objB) { SpatialKey a = (SpatialKey) objA; SpatialKey b = (SpatialKey) objB; if (a.isNull() || b.isNull()) { return false; } for (int i = 0; i < dimensions; i++) { if (a.min(i) > b.min(i) || a.max(i) < b.max(i)) { return false; } } return true; }
/** * Increase the bounds in the given spatial object. * * @param bounds the bounds (may be modified) * @param add the value */ public void increaseBounds(Object bounds, Object add) { SpatialKey a = (SpatialKey) add; SpatialKey b = (SpatialKey) bounds; if (a.isNull() || b.isNull()) { return; } for (int i = 0; i < dimensions; i++) { b.setMin(i, Math.min(b.min(i), a.min(i))); b.setMax(i, Math.max(b.max(i), a.max(i))); } }
/** * Get the combined area of both objects. * * @param objA the first object * @param objB the second object * @return the area */ float getCombinedArea(Object objA, Object objB) { SpatialKey a = (SpatialKey) objA; SpatialKey b = (SpatialKey) objB; if (a.isNull()) { return getArea(b); } else if (b.isNull()) { return getArea(a); } float area = 1; for (int i = 0; i < dimensions; i++) { float min = Math.min(a.min(i), b.min(i)); float max = Math.max(a.max(i), b.max(i)); area *= max - min; } return area; }
/** * Create a bounding box starting with the given object. * * @param objA the object * @return the bounding box */ Object createBoundingBox(Object objA) { SpatialKey a = (SpatialKey) objA; if (a.isNull()) { return a; } float[] minMax = new float[dimensions * 2]; for (int i = 0; i < dimensions; i++) { minMax[i + i] = a.min(i); minMax[i + i + 1] = a.max(i); } return new SpatialKey(0, minMax); }
SpatialKey boundsInner = (SpatialKey) createBoundingBox(bounds); for (int i = 0; i < dimensions; i++) { float t = boundsInner.min(i); boundsInner.setMin(i, boundsInner.max(i)); boundsInner.setMax(i, t); int bestDim = 0; for (int i = 0; i < dimensions; i++) { float inner = boundsInner.max(i) - boundsInner.min(i); if (inner < 0) { continue; float outer = bounds.max(i) - bounds.min(i); float d = inner / outer; if (d > best) { return null; float min = boundsInner.min(bestDim); float max = boundsInner.max(bestDim); int firstIndex = -1, lastIndex = -1; if (firstIndex < 0 && o.max(bestDim) == min) { firstIndex = i; } else if (lastIndex < 0 && o.min(bestDim) == max) { lastIndex = i;
@Override public void write(WriteBuffer buff, Object obj) { SpatialKey k = (SpatialKey) obj; if (k.isNull()) { buff.putVarInt(-1); buff.putVarLong(k.getId()); return; } int flags = 0; for (int i = 0; i < dimensions; i++) { if (k.min(i) == k.max(i)) { flags |= 1 << i; } } buff.putVarInt(flags); for (int i = 0; i < dimensions; i++) { buff.putFloat(k.min(i)); if ((flags & (1 << i)) == 0) { buff.putFloat(k.max(i)); } } buff.putVarLong(k.getId()); }
private float getArea(SpatialKey a) { if (a.isNull()) { return 0; } float area = 1; for (int i = 0; i < dimensions; i++) { area *= a.max(i) - a.min(i); } return area; }
private float getArea(SpatialKey a) { if (a.isNull()) { return 0; } float area = 1; for (int i = 0; i < dimensions; i++) { area *= a.max(i) - a.min(i); } return area; }
private float getArea(SpatialKey a) { if (a.isNull()) { return 0; } float area = 1; for (int i = 0; i < dimensions; i++) { area *= a.max(i) - a.min(i); } return area; }
/** * Increase the bounds in the given spatial object. * * @param bounds the bounds (may be modified) * @param add the value */ public void increaseBounds(Object bounds, Object add) { SpatialKey a = (SpatialKey) add; SpatialKey b = (SpatialKey) bounds; if (a.isNull() || b.isNull()) { return; } for (int i = 0; i < dimensions; i++) { b.setMin(i, Math.min(b.min(i), a.min(i))); b.setMax(i, Math.max(b.max(i), a.max(i))); } }
/** * Increase the bounds in the given spatial object. * * @param bounds the bounds (may be modified) * @param add the value */ public void increaseBounds(Object bounds, Object add) { SpatialKey a = (SpatialKey) add; SpatialKey b = (SpatialKey) bounds; if (a.isNull() || b.isNull()) { return; } for (int i = 0; i < dimensions; i++) { b.setMin(i, Math.min(b.min(i), a.min(i))); b.setMax(i, Math.max(b.max(i), a.max(i))); } }
/** * Create a bounding box starting with the given object. * * @param objA the object * @return the bounding box */ Object createBoundingBox(Object objA) { SpatialKey a = (SpatialKey) objA; if (a.isNull()) { return a; } float[] minMax = new float[dimensions * 2]; for (int i = 0; i < dimensions; i++) { minMax[i + i] = a.min(i); minMax[i + i + 1] = a.max(i); } return new SpatialKey(0, minMax); }