Hello,
I have been using a couple of methods to calculate whether a point is inside a line that may be interesting for others. For example, I use this to know whether a bullet is within its calculated path (it will have collided when it's not). I also added some documentation to the class.
I may have misunderstood the internals of LineSegment (I got confused about whether the the origin of the LineSegment is the center of one of its ends. I assume it's the former).
Here is the code for the added methods and the patch for everything is below.
/**
* <p>Returns the axis aligned bounding box that contains this LineSegment.</p>
* @see LineSegment#getBoundingBox(BoundingBox)
* @see BoundingBox
*/
public BoundingBox getBoundingBox() {
return getBoundingBox(null);
}
/**
* <p>Returns the axis aligned bounding box that contains this LineSegment.</p>
* <p>Accepts a BoundingBox to store the result, and will create a new one if
* null is passed. The BoundingBox is returned as result.</p>
* @see BoundingBox
*/
public BoundingBox getBoundingBox(BoundingBox store) {
if (store == null) store = new BoundingBox();
store.xExtent = direction.x * extent;
store.yExtent = direction.y * extent;
store.zExtent = direction.z * extent;
store.getCenter().set(origin);
return store;
}
/**
* <p>Evaluates whether a given point is contained within the axis aligned bounding box
* that contains this LineSegment.</p><p>This function is float error aware.</p>
*/
public boolean pointInsideBounds(Vector3f point) {
return pointInsideBounds(point, Float.MIN_VALUE * 2);
}
/**
* <p>Evaluates whether a given point is contained within the axis aligned bounding box
* that contains this LineSegment.</p><p>This function accepts an error parameter, which
* is added to the extent of the bounding box.</p>
*/
public boolean pointInsideBounds(Vector3f point, float error) {
if (FastMath.abs(point.x - origin.x) > FastMath.abs(direction.x * extent) + error) return false;
if (FastMath.abs(point.y - origin.y) > FastMath.abs(direction.y * extent) + error) return false;
if (FastMath.abs(point.z - origin.z) > FastMath.abs(direction.z * extent) + error) return false;
return true;
}
Index: C:/Documents and Settings/jjmontes/Mis documentos/Proyectos/jme2/jme2/src/com/jme/math/LineSegment.java
===================================================================
--- C:/Documents and Settings/jjmontes/Mis documentos/Proyectos/jme2/jme2/src/com/jme/math/LineSegment.java (revision 4054)
+++ C:/Documents and Settings/jjmontes/Mis documentos/Proyectos/jme2/jme2/src/com/jme/math/LineSegment.java (working copy)
@@ -34,6 +34,7 @@
import java.io.IOException;
import java.io.Serializable;
+import com.jme.bounding.BoundingBox;
import com.jme.util.export.InputCapsule;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
@@ -41,8 +42,18 @@
import com.jme.util.export.Savable;
/**
- * <code>LineSegment</code>
- *
+ * <p>LineSegment represents a segment in the space. This is a portion of a Line
+ * that has a limited start and end points.</p>
+ * <p>A LineSegment is defined by an origin, a direction and an extent (or length).
+ * Direction should be a normalized vector. It is not internally normalized.</p>
+ * <p>This class provides methods to calculate distances between LineSegments, Rays and Vectors.
+ * It is also possible to retrieve both end points of the segment {@link LineSegment#getPositiveEnd(Vector3f)}
+ * and {@link LineSegment#getNegativeEnd(Vector3f)}. There are also methods to check whether
+ * a point is within the Segment bounds.</p>
+ *
+ * @see LineSegment
+ * @see Ray
+ * @see Vector3f
* @author Mark Powell
* @author Joshua Slack
*/
@@ -69,12 +80,27 @@
this.extent = ls.getExtent();
}
+ /**
+ * <p>Creates a new LineSegment with the given origin, direction and extent.</p>
+ * <p>Note that the origin is not one of the ends of the LineSegment, but its center.</p>
+ */
public LineSegment(Vector3f origin, Vector3f direction, float extent) {
this.origin = origin;
this.direction = direction;
this.extent = extent;
}
+ /**
+ * <p>Creates a new LineSegment with a given origin and end. This constructor will calculate the
+ * center, the direction and the extent.</p>
+ */
+ public LineSegment(Vector3f start, Vector3f end) {
+ this.origin = new Vector3f(0.5f * (start.x + end.x), 0.5f * (start.y + end.y), 0.5f * (start.z + end.z));
+ this.direction = end.subtract(start);
+ this.extent = direction.length();
+ direction.normalizeLocal();
+ }
+
public void set(LineSegment ls) {
this.origin = new Vector3f(ls.getOrigin());
this.direction = new Vector3f(ls.getDirection());
@@ -566,7 +592,7 @@
direction = (Vector3f)capsule.readSavable("direction", Vector3f.ZERO.clone());
extent = capsule.readFloat("extent", 0);
}
-
+
public Class<? extends LineSegment> getClassTag() {
return this.getClass();
}
@@ -582,4 +608,52 @@
throw new AssertionError();
}
}
+
+ /**
+ * <p>Returns the axis aligned bounding box that contains this LineSegment.</p>
+ * @see LineSegment#getBoundingBox(BoundingBox)
+ * @see BoundingBox
+ */
+ public BoundingBox getBoundingBox() {
+ return getBoundingBox(null);
+ }
+
+ /**
+ * <p>Returns the axis aligned bounding box that contains this LineSegment.</p>
+ * <p>Accepts a BoundingBox to store the result, and will create a new one if
+ * null is passed. The BoundingBox is returned as result.</p>
+ * @see BoundingBox
+ */
+ public BoundingBox getBoundingBox(BoundingBox store) {
+ if (store == null) store = new BoundingBox();
+ store.xExtent = direction.x * extent;
+ store.yExtent = direction.y * extent;
+ store.zExtent = direction.z * extent;
+ store.getCenter().set(origin);
+ return store;
+ }
+
+
+ /**
+ * <p>Evaluates whether a given point is contained within the axis aligned bounding box
+ * that contains this LineSegment.</p><p>This function is float error aware.</p>
+ */
+ public boolean pointInsideBounds(Vector3f point) {
+ return pointInsideBounds(point, Float.MIN_VALUE * 2);
+ }
+
+ /**
+ * <p>Evaluates whether a given point is contained within the axis aligned bounding box
+ * that contains this LineSegment.</p><p>This function accepts an error parameter, which
+ * is added to the extent of the bounding box.</p>
+ */
+ public boolean pointInsideBounds(Vector3f point, float error) {
+
+ if (FastMath.abs(point.x - origin.x) > FastMath.abs(direction.x * extent) + error) return false;
+ if (FastMath.abs(point.y - origin.y) > FastMath.abs(direction.y * extent) + error) return false;
+ if (FastMath.abs(point.z - origin.z) > FastMath.abs(direction.z * extent) + error) return false;
+
+ return true;
+ }
+
}