mirror of
https://github.com/apache/commons-math.git
synced 2025-02-08 19:15:18 +00:00
Added a 3D SubLine class.
JIRA: MATH-593 git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1159353 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
290621a860
commit
d7121b1c0b
@ -16,10 +16,11 @@
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.threed;
|
||||
|
||||
import org.apache.commons.math.exception.MathArithmeticException;
|
||||
import org.apache.commons.math.exception.MathIllegalArgumentException;
|
||||
import org.apache.commons.math.exception.util.LocalizedFormats;
|
||||
import org.apache.commons.math.geometry.Vector;
|
||||
import org.apache.commons.math.geometry.euclidean.oned.Euclidean1D;
|
||||
import org.apache.commons.math.geometry.euclidean.oned.IntervalsSet;
|
||||
import org.apache.commons.math.geometry.euclidean.oned.Vector1D;
|
||||
import org.apache.commons.math.geometry.partitioning.Embedding;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
@ -28,7 +29,7 @@ import org.apache.commons.math.util.MathUtils;
|
||||
/** The class represent lines in a three dimensional space.
|
||||
|
||||
* <p>Each oriented line is intrinsically associated with an abscissa
|
||||
* wich is a coordinate on the line. The point at abscissa 0 is the
|
||||
* which is a coordinate on the line. The point at abscissa 0 is the
|
||||
* orthogonal projection of the origin on the line, another equivalent
|
||||
* way to express this is to say that it is the point of the line
|
||||
* which is closest to the origin. Abscissa increases in the line
|
||||
@ -45,13 +46,13 @@ public class Line implements Embedding<Euclidean3D, Euclidean1D> {
|
||||
/** Line point closest to the origin. */
|
||||
private Vector3D zero;
|
||||
|
||||
/** Build a line from a point and a direction.
|
||||
* @param p point belonging to the line (this can be any point)
|
||||
* @param direction direction of the line
|
||||
* @exception MathArithmeticException if the direction norm is too small
|
||||
/** Build a line from two points.
|
||||
* @param p1 first point belonging to the line (this can be any point)
|
||||
* @param p2 second point belonging to the line (this can be any point, different from p1)
|
||||
* @exception MathIllegalArgumentException if the points are equal
|
||||
*/
|
||||
public Line(final Vector3D p, final Vector3D direction) {
|
||||
reset(p, direction);
|
||||
public Line(final Vector3D p1, final Vector3D p2) {
|
||||
reset(p1, p2);
|
||||
}
|
||||
|
||||
/** Copy constructor.
|
||||
@ -64,25 +65,26 @@ public class Line implements Embedding<Euclidean3D, Euclidean1D> {
|
||||
this.zero = line.zero;
|
||||
}
|
||||
|
||||
/** Reset the instance as if built from a point and a normal.
|
||||
* @param p point belonging to the line (this can be any point)
|
||||
* @param dir direction of the line
|
||||
* @exception MathArithmeticException if the direction norm is too small
|
||||
/** Reset the instance as if built from two points.
|
||||
* @param p1 first point belonging to the line (this can be any point)
|
||||
* @param p2 second point belonging to the line (this can be any point, different from p1)
|
||||
* @exception MathIllegalArgumentException if the points are equal
|
||||
*/
|
||||
public void reset(final Vector3D p, final Vector3D dir) {
|
||||
final double norm = dir.getNorm();
|
||||
if (norm == 0.0) {
|
||||
throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
|
||||
public void reset(final Vector3D p1, final Vector3D p2) {
|
||||
final Vector3D delta = p2.subtract(p1);
|
||||
final double norm2 = delta.getNormSq();
|
||||
if (norm2 == 0.0) {
|
||||
throw new MathIllegalArgumentException(LocalizedFormats.ZERO_NORM);
|
||||
}
|
||||
this.direction = new Vector3D(1.0 / norm, dir);
|
||||
zero = new Vector3D(1.0, p, -p.dotProduct(this.direction), this.direction);
|
||||
this.direction = new Vector3D(1.0 / FastMath.sqrt(norm2), delta);
|
||||
zero = new Vector3D(1.0, p1, -p1.dotProduct(delta) / norm2, delta);
|
||||
}
|
||||
|
||||
/** Get a line with reversed direction.
|
||||
* @return a new instance, with reversed direction
|
||||
*/
|
||||
public Line revert() {
|
||||
return new Line(zero, direction.negate());
|
||||
return new Line(zero, zero.subtract(direction));
|
||||
}
|
||||
|
||||
/** Get the normalized direction vector.
|
||||
@ -213,4 +215,11 @@ public class Line implements Embedding<Euclidean3D, Euclidean1D> {
|
||||
return line.contains(closest) ? closest : null;
|
||||
}
|
||||
|
||||
/** Build a sub-line covering the whole line.
|
||||
* @return a sub-line covering the whole line
|
||||
*/
|
||||
public SubLine wholeLine() {
|
||||
return new SubLine(this, new IntervalsSet());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -323,8 +323,8 @@ public class Plane implements Hyperplane<Euclidean3D>, Embedding<Euclidean3D, Eu
|
||||
if (direction.getNorm() < 1.0e-10) {
|
||||
return null;
|
||||
}
|
||||
return new Line(intersection(this, other, new Plane(direction)),
|
||||
direction);
|
||||
final Vector3D point = intersection(this, other, new Plane(direction));
|
||||
return new Line(point, point.add(direction));
|
||||
}
|
||||
|
||||
/** Get the intersection point of three planes.
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.threed;
|
||||
|
||||
|
||||
/** Simple container for a two-points segment.
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Segment {
|
||||
|
||||
/** Start point of the segment. */
|
||||
private final Vector3D start;
|
||||
|
||||
/** End point of the segments. */
|
||||
private final Vector3D end;
|
||||
|
||||
/** Line containing the segment. */
|
||||
private final Line line;
|
||||
|
||||
/** Build a segment.
|
||||
* @param start start point of the segment
|
||||
* @param end end point of the segment
|
||||
* @param line line containing the segment
|
||||
*/
|
||||
public Segment(final Vector3D start, final Vector3D end, final Line line) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
/** Get the start point of the segment.
|
||||
* @return start point of the segment
|
||||
*/
|
||||
public Vector3D getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
/** Get the end point of the segment.
|
||||
* @return end point of the segment
|
||||
*/
|
||||
public Vector3D getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
/** Get the line containing the segment.
|
||||
* @return line containing the segment
|
||||
*/
|
||||
public Line getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.threed;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.math.geometry.euclidean.oned.Interval;
|
||||
import org.apache.commons.math.geometry.euclidean.oned.IntervalsSet;
|
||||
import org.apache.commons.math.geometry.euclidean.oned.Vector1D;
|
||||
import org.apache.commons.math.geometry.partitioning.Hyperplane;
|
||||
import org.apache.commons.math.geometry.partitioning.Region.Location;
|
||||
|
||||
/** This class represents a subset of a {@link Line}.
|
||||
* @version $Id$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SubLine {
|
||||
|
||||
/** Underlying line. */
|
||||
private final Line line;
|
||||
|
||||
/** Remaining region of the hyperplane. */
|
||||
private final IntervalsSet remainingRegion;
|
||||
|
||||
/** Simple constructor.
|
||||
* @param line underlying line
|
||||
* @param remainingRegion remaining region of the line
|
||||
*/
|
||||
public SubLine(final Line line, final IntervalsSet remainingRegion) {
|
||||
this.line = line;
|
||||
this.remainingRegion = remainingRegion;
|
||||
}
|
||||
|
||||
/** Create a sub-line from two endpoints.
|
||||
* @param start start point
|
||||
* @param end end point
|
||||
*/
|
||||
public SubLine(final Vector3D start, final Vector3D end) {
|
||||
this(new Line(start, end), buildIntervalSet(start, end));
|
||||
}
|
||||
|
||||
/** Create a sub-line from a segment.
|
||||
* @param segment single segment forming the sub-line
|
||||
*/
|
||||
public SubLine(final Segment segment) {
|
||||
this(segment.getLine(), buildIntervalSet(segment.getStart(), segment.getEnd()));
|
||||
}
|
||||
|
||||
/** Get the endpoints of the sub-line.
|
||||
* <p>
|
||||
* A subline may be any arbitrary number of disjoints segments, so the endpoints
|
||||
* are provided as a list of endpoint pairs. Each element of the list represents
|
||||
* one segment, and each segment contains a start point at index 0 and an end point
|
||||
* at index 1. If the sub-line is unbounded in the negative infinity direction,
|
||||
* the start point of the first segment will have infinite coordinates. If the
|
||||
* sub-line is unbounded in the positive infinity direction, the end point of the
|
||||
* last segment will have infinite coordinates. So a sub-line covering the whole
|
||||
* line will contain just one row and both elements of this row will have infinite
|
||||
* coordinates. If the sub-line is empty, the returned list will contain 0 segments.
|
||||
* </p>
|
||||
* @return list of segments endpoints
|
||||
*/
|
||||
public List<Segment> getSegments() {
|
||||
|
||||
final List<Interval> list = remainingRegion.asList();
|
||||
final List<Segment> segments = new ArrayList<Segment>();
|
||||
|
||||
for (final Interval interval : list) {
|
||||
final Vector3D start = line.toSpace(new Vector1D(interval.getLower()));
|
||||
final Vector3D end = line.toSpace(new Vector1D(interval.getUpper()));
|
||||
segments.add(new Segment(start, end, line));
|
||||
}
|
||||
|
||||
return segments;
|
||||
|
||||
}
|
||||
|
||||
/** Get the intersection of the instance and another sub-line.
|
||||
* <p>
|
||||
* This method is related to the {@link Line#intersection(Hyperplane)
|
||||
* intersection} method in the {@link Line Line} class, but in addition
|
||||
* to compute the point along infinite lines, it also checks the point
|
||||
* lies on both sub-line ranges.
|
||||
* </p>
|
||||
* @param subLine other sub-line which may intersect instance
|
||||
* @param includeEndPoints if true, endpoints are considered to belong to
|
||||
* instance (i.e. they are closed sets) and may be returned, otherwise endpoints
|
||||
* are considered to not belong to instance (i.e. they are open sets) and intersection
|
||||
* occurring on endpoints lead to null being returned
|
||||
* @return the intersection point if there is one, null if the sub-lines don't intersect
|
||||
*/
|
||||
public Vector3D intersection(final SubLine subLine, final boolean includeEndPoints) {
|
||||
|
||||
// compute the intersection on infinite line
|
||||
Vector3D v1D = line.intersection(subLine.line);
|
||||
|
||||
// check location of point with respect to first sub-line
|
||||
Location loc1 = remainingRegion.checkPoint(line.toSubSpace(v1D));
|
||||
|
||||
// check location of point with respect to second sub-line
|
||||
Location loc2 = subLine.remainingRegion.checkPoint(subLine.line.toSubSpace(v1D));
|
||||
|
||||
if (includeEndPoints) {
|
||||
return ((loc1 != Location.OUTSIDE) && (loc2 != Location.OUTSIDE)) ? v1D : null;
|
||||
} else {
|
||||
return ((loc1 == Location.INSIDE) && (loc2 == Location.INSIDE)) ? v1D : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Build an interval set from two points.
|
||||
* @param start start point
|
||||
* @param end end point
|
||||
* @return an interval set
|
||||
*/
|
||||
private static IntervalsSet buildIntervalSet(final Vector3D start, final Vector3D end) {
|
||||
final Line line = new Line(start, end);
|
||||
return new IntervalsSet(line.toSubSpace(start).getX(),
|
||||
line.toSubSpace(end).getX());
|
||||
}
|
||||
|
||||
}
|
@ -52,6 +52,9 @@ The <action> type attribute can be add,update,fix,remove.
|
||||
If the output is not quite correct, check for invisible trailing spaces!
|
||||
-->
|
||||
<release version="3.0" date="TBD" description="TBD">
|
||||
<action dev="luc" type="add" issue="MATH-593">
|
||||
Added a 3D SubLine class.
|
||||
</action>
|
||||
<action dev="erans" type="fix" issue="MATH-645">
|
||||
Fixed exceptions generated by "ebeMultiply" and "ebeDivide" in "OpenMapRealVector".
|
||||
</action>
|
||||
|
@ -27,7 +27,7 @@ public class LineTest {
|
||||
@Test
|
||||
public void testContains() {
|
||||
Vector3D p1 = new Vector3D(0, 0, 1);
|
||||
Line l = new Line(p1, new Vector3D(0, 0, 1));
|
||||
Line l = new Line(p1, new Vector3D(0, 0, 2));
|
||||
Assert.assertTrue(l.contains(p1));
|
||||
Assert.assertTrue(l.contains(new Vector3D(1.0, p1, 0.3, l.getDirection())));
|
||||
Vector3D u = l.getDirection().orthogonal();
|
||||
@ -42,89 +42,89 @@ public class LineTest {
|
||||
public void testSimilar() {
|
||||
Vector3D p1 = new Vector3D (1.2, 3.4, -5.8);
|
||||
Vector3D p2 = new Vector3D (3.4, -5.8, 1.2);
|
||||
Line lA = new Line(p1, p2.subtract(p1));
|
||||
Line lB = new Line(p2, p1.subtract(p2));
|
||||
Line lA = new Line(p1, p2);
|
||||
Line lB = new Line(p2, p1);
|
||||
Assert.assertTrue(lA.isSimilarTo(lB));
|
||||
Assert.assertTrue(! lA.isSimilarTo(new Line(p1, lA.getDirection().orthogonal())));
|
||||
Assert.assertTrue(! lA.isSimilarTo(new Line(p1, p1.add(lA.getDirection().orthogonal()))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointDistance() {
|
||||
Line l = new Line(new Vector3D(0, 1, 1), new Vector3D(0, 1, 1));
|
||||
Line l = new Line(new Vector3D(0, 1, 1), new Vector3D(0, 2, 2));
|
||||
Assert.assertEquals(FastMath.sqrt(3.0 / 2.0), l.distance(new Vector3D(1, 0, 1)), 1.0e-10);
|
||||
Assert.assertEquals(0, l.distance(new Vector3D(0, -4, -4)), 1.0e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLineDistance() {
|
||||
Line l = new Line(new Vector3D(0, 1, 1), new Vector3D(0, 1, 1));
|
||||
Line l = new Line(new Vector3D(0, 1, 1), new Vector3D(0, 2, 2));
|
||||
Assert.assertEquals(1.0,
|
||||
l.distance(new Line(new Vector3D(1, 0, 1), Vector3D.PLUS_K)),
|
||||
l.distance(new Line(new Vector3D(1, 0, 1), new Vector3D(1, 0, 2))),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.5,
|
||||
l.distance(new Line(new Vector3D(-0.5, 0, 0), new Vector3D(0, -1, -1))),
|
||||
l.distance(new Line(new Vector3D(-0.5, 0, 0), new Vector3D(-0.5, -1, -1))),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.distance(l),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.distance(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -1, -1))),
|
||||
l.distance(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -5, -5))),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.distance(new Line(new Vector3D(0, -4, -4), new Vector3D(0, 1, 0))),
|
||||
l.distance(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -3, -4))),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.distance(new Line(new Vector3D(0, -4, -4), new Vector3D(1, 0, 0))),
|
||||
l.distance(new Line(new Vector3D(0, -4, -4), new Vector3D(1, -4, -4))),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(FastMath.sqrt(8),
|
||||
l.distance(new Line(new Vector3D(0, -4, 0), new Vector3D(1, 0, 0))),
|
||||
l.distance(new Line(new Vector3D(0, -4, 0), new Vector3D(1, -4, 0))),
|
||||
1.0e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClosest() {
|
||||
Line l = new Line(new Vector3D(0, 1, 1), new Vector3D(0, 1, 1));
|
||||
Line l = new Line(new Vector3D(0, 1, 1), new Vector3D(0, 2, 2));
|
||||
Assert.assertEquals(0.0,
|
||||
l.closestPoint(new Line(new Vector3D(1, 0, 1), Vector3D.PLUS_K)).distance(new Vector3D(0, 0, 0)),
|
||||
l.closestPoint(new Line(new Vector3D(1, 0, 1), new Vector3D(1, 0, 2))).distance(new Vector3D(0, 0, 0)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.5,
|
||||
l.closestPoint(new Line(new Vector3D(-0.5, 0, 0), new Vector3D(0, -1, -1))).distance(new Vector3D(-0.5, 0, 0)),
|
||||
l.closestPoint(new Line(new Vector3D(-0.5, 0, 0), new Vector3D(-0.5, -1, -1))).distance(new Vector3D(-0.5, 0, 0)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.closestPoint(l).distance(new Vector3D(0, 0, 0)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.closestPoint(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -1, -1))).distance(new Vector3D(0, 0, 0)),
|
||||
l.closestPoint(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -5, -5))).distance(new Vector3D(0, 0, 0)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.closestPoint(new Line(new Vector3D(0, -4, -4), new Vector3D(0, 1, 0))).distance(new Vector3D(0, -4, -4)),
|
||||
l.closestPoint(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -3, -4))).distance(new Vector3D(0, -4, -4)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.closestPoint(new Line(new Vector3D(0, -4, -4), new Vector3D(1, 0, 0))).distance(new Vector3D(0, -4, -4)),
|
||||
l.closestPoint(new Line(new Vector3D(0, -4, -4), new Vector3D(1, -4, -4))).distance(new Vector3D(0, -4, -4)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.closestPoint(new Line(new Vector3D(0, -4, 0), new Vector3D(1, 0, 0))).distance(new Vector3D(0, -2, -2)),
|
||||
l.closestPoint(new Line(new Vector3D(0, -4, 0), new Vector3D(1, -4, 0))).distance(new Vector3D(0, -2, -2)),
|
||||
1.0e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersection() {
|
||||
Line l = new Line(new Vector3D(0, 1, 1), new Vector3D(0, 1, 1));
|
||||
Assert.assertNull(l.intersection(new Line(new Vector3D(1, 0, 1), Vector3D.PLUS_K)));
|
||||
Assert.assertNull(l.intersection(new Line(new Vector3D(-0.5, 0, 0), new Vector3D(0, -1, -1))));
|
||||
Line l = new Line(new Vector3D(0, 1, 1), new Vector3D(0, 2, 2));
|
||||
Assert.assertNull(l.intersection(new Line(new Vector3D(1, 0, 1), new Vector3D(1, 0, 2))));
|
||||
Assert.assertNull(l.intersection(new Line(new Vector3D(-0.5, 0, 0), new Vector3D(-0.5, -1, -1))));
|
||||
Assert.assertEquals(0.0,
|
||||
l.intersection(l).distance(new Vector3D(0, 0, 0)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.intersection(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -1, -1))).distance(new Vector3D(0, 0, 0)),
|
||||
l.intersection(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -5, -5))).distance(new Vector3D(0, 0, 0)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.intersection(new Line(new Vector3D(0, -4, -4), new Vector3D(0, 1, 0))).distance(new Vector3D(0, -4, -4)),
|
||||
l.intersection(new Line(new Vector3D(0, -4, -4), new Vector3D(0, -3, -4))).distance(new Vector3D(0, -4, -4)),
|
||||
1.0e-10);
|
||||
Assert.assertEquals(0.0,
|
||||
l.intersection(new Line(new Vector3D(0, -4, -4), new Vector3D(1, 0, 0))).distance(new Vector3D(0, -4, -4)),
|
||||
l.intersection(new Line(new Vector3D(0, -4, -4), new Vector3D(1, -4, -4))).distance(new Vector3D(0, -4, -4)),
|
||||
1.0e-10);
|
||||
Assert.assertNull(l.intersection(new Line(new Vector3D(0, -4, 0), new Vector3D(1, 0, 0))));
|
||||
Assert.assertNull(l.intersection(new Line(new Vector3D(0, -4, 0), new Vector3D(1, -4, 0))));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -116,12 +116,12 @@ public class PlaneTest {
|
||||
@Test
|
||||
public void testIntersection() {
|
||||
Plane p = new Plane(new Vector3D(1, 2, 3), new Vector3D(-4, 1, -5));
|
||||
Line l = new Line(new Vector3D(0.2, -3.5, 0.7), new Vector3D(1, 1, -1));
|
||||
Line l = new Line(new Vector3D(0.2, -3.5, 0.7), new Vector3D(1.2, -2.5, -0.3));
|
||||
Vector3D point = p.intersection(l);
|
||||
Assert.assertTrue(p.contains(point));
|
||||
Assert.assertTrue(l.contains(point));
|
||||
Assert.assertNull(p.intersection(new Line(new Vector3D(10, 10, 10),
|
||||
p.getNormal().orthogonal())));
|
||||
new Vector3D(10, 10, 10).add(p.getNormal().orthogonal()))));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.threed;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.math.geometry.euclidean.oned.Euclidean1D;
|
||||
import org.apache.commons.math.geometry.euclidean.oned.IntervalsSet;
|
||||
import org.apache.commons.math.geometry.partitioning.RegionFactory;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SubLineTest {
|
||||
|
||||
@Test
|
||||
public void testEndPoints() {
|
||||
Vector3D p1 = new Vector3D(-1, -7, 2);
|
||||
Vector3D p2 = new Vector3D(7, -1, 0);
|
||||
Segment segment = new Segment(p1, p2, new Line(p1, p2));
|
||||
SubLine sub = new SubLine(segment);
|
||||
List<Segment> segments = sub.getSegments();
|
||||
Assert.assertEquals(1, segments.size());
|
||||
Assert.assertEquals(0.0, new Vector3D(-1, -7, 2).distance(segments.get(0).getStart()), 1.0e-10);
|
||||
Assert.assertEquals(0.0, new Vector3D( 7, -1, 0).distance(segments.get(0).getEnd()), 1.0e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoEndPoints() {
|
||||
SubLine wholeLine = new Line(new Vector3D(-1, 7, 2), new Vector3D(7, 1, 0)).wholeLine();
|
||||
List<Segment> segments = wholeLine.getSegments();
|
||||
Assert.assertEquals(1, segments.size());
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getStart().getX()) &&
|
||||
segments.get(0).getStart().getX() < 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getStart().getY()) &&
|
||||
segments.get(0).getStart().getY() > 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getStart().getZ()) &&
|
||||
segments.get(0).getStart().getZ() > 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getEnd().getX()) &&
|
||||
segments.get(0).getEnd().getX() > 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getEnd().getY()) &&
|
||||
segments.get(0).getEnd().getY() < 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getEnd().getZ()) &&
|
||||
segments.get(0).getEnd().getZ() < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSegments() {
|
||||
SubLine empty = new SubLine(new Line(new Vector3D(-1, -7, 2), new Vector3D(7, -1, 0)),
|
||||
(IntervalsSet) new RegionFactory<Euclidean1D>().getComplement(new IntervalsSet()));
|
||||
List<Segment> segments = empty.getSegments();
|
||||
Assert.assertEquals(0, segments.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSeveralSegments() {
|
||||
SubLine twoSubs = new SubLine(new Line(new Vector3D(-1, -7, 2), new Vector3D(7, -1, 0)),
|
||||
(IntervalsSet) new RegionFactory<Euclidean1D>().union(new IntervalsSet(1, 2),
|
||||
new IntervalsSet(3, 4)));
|
||||
List<Segment> segments = twoSubs.getSegments();
|
||||
Assert.assertEquals(2, segments.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHalfInfiniteNeg() {
|
||||
SubLine empty = new SubLine(new Line(new Vector3D(-1, -7, 2), new Vector3D(7, -1, -2)),
|
||||
new IntervalsSet(Double.NEGATIVE_INFINITY, 0.0));
|
||||
List<Segment> segments = empty.getSegments();
|
||||
Assert.assertEquals(1, segments.size());
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getStart().getX()) &&
|
||||
segments.get(0).getStart().getX() < 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getStart().getY()) &&
|
||||
segments.get(0).getStart().getY() < 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getStart().getZ()) &&
|
||||
segments.get(0).getStart().getZ() > 0);
|
||||
Assert.assertEquals(0.0, new Vector3D(3, -4, 0).distance(segments.get(0).getEnd()), 1.0e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHalfInfinitePos() {
|
||||
SubLine empty = new SubLine(new Line(new Vector3D(-1, -7, 2), new Vector3D(7, -1, -2)),
|
||||
new IntervalsSet(0.0, Double.POSITIVE_INFINITY));
|
||||
List<Segment> segments = empty.getSegments();
|
||||
Assert.assertEquals(1, segments.size());
|
||||
Assert.assertEquals(0.0, new Vector3D(3, -4, 0).distance(segments.get(0).getStart()), 1.0e-10);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getEnd().getX()) &&
|
||||
segments.get(0).getEnd().getX() > 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getEnd().getY()) &&
|
||||
segments.get(0).getEnd().getY() > 0);
|
||||
Assert.assertTrue(Double.isInfinite(segments.get(0).getEnd().getZ()) &&
|
||||
segments.get(0).getEnd().getZ() < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersectionInsideInside() {
|
||||
SubLine sub1 = new SubLine(new Vector3D(1, 1, 1), new Vector3D(3, 1, 1));
|
||||
SubLine sub2 = new SubLine(new Vector3D(2, 0, 0), new Vector3D(2, 2, 2));
|
||||
Assert.assertEquals(0.0, new Vector3D(2, 1, 1).distance(sub1.intersection(sub2, true)), 1.0e-12);
|
||||
Assert.assertEquals(0.0, new Vector3D(2, 1, 1).distance(sub1.intersection(sub2, false)), 1.0e-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersectionInsideBoundary() {
|
||||
SubLine sub1 = new SubLine(new Vector3D(1, 1, 1), new Vector3D(3, 1, 1));
|
||||
SubLine sub2 = new SubLine(new Vector3D(2, 0, 0), new Vector3D(2, 1, 1));
|
||||
Assert.assertEquals(0.0, new Vector3D(2, 1, 1).distance(sub1.intersection(sub2, true)), 1.0e-12);
|
||||
Assert.assertNull(sub1.intersection(sub2, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersectionInsideOutside() {
|
||||
SubLine sub1 = new SubLine(new Vector3D(1, 1, 1), new Vector3D(3, 1, 1));
|
||||
SubLine sub2 = new SubLine(new Vector3D(2, 0, 0), new Vector3D(2, 0.5, 0.5));
|
||||
Assert.assertNull(sub1.intersection(sub2, true));
|
||||
Assert.assertNull(sub1.intersection(sub2, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersectionBoundaryBoundary() {
|
||||
SubLine sub1 = new SubLine(new Vector3D(1, 1, 1), new Vector3D(2, 1, 1));
|
||||
SubLine sub2 = new SubLine(new Vector3D(2, 0, 0), new Vector3D(2, 1, 1));
|
||||
Assert.assertEquals(0.0, new Vector3D(2, 1, 1).distance(sub1.intersection(sub2, true)), 1.0e-12);
|
||||
Assert.assertNull(sub1.intersection(sub2, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersectionBoundaryOutside() {
|
||||
SubLine sub1 = new SubLine(new Vector3D(1, 1, 1), new Vector3D(2, 1, 1));
|
||||
SubLine sub2 = new SubLine(new Vector3D(2, 0, 0), new Vector3D(2, 0.5, 0.5));
|
||||
Assert.assertNull(sub1.intersection(sub2, true));
|
||||
Assert.assertNull(sub1.intersection(sub2, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersectionOutsideOutside() {
|
||||
SubLine sub1 = new SubLine(new Vector3D(1, 1, 1), new Vector3D(1.5, 1, 1));
|
||||
SubLine sub2 = new SubLine(new Vector3D(2, 0, 0), new Vector3D(2, 0.5, 0.5));
|
||||
Assert.assertNull(sub1.intersection(sub2, true));
|
||||
Assert.assertNull(sub1.intersection(sub2, false));
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user