Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GEOMETRY-150: implemented a way to check if 2 vectors are codirectional #216

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,13 @@ public interface Vector<V extends Vector<V>> extends Spatial {
* @throws IllegalArgumentException if either vector has a zero, NaN, or infinite norm
*/
double angle(V v);

/** Checks if the two vectors point at the same direction.
* This means that each vector can be obtained from the other by multiplying by a positive scalar.
* Any vector is considered as codirectional to a zero vector.
* @param v other vector
* @return {@code true} if both vectors point at the same direction.
* @throws IllegalArgumentException if either vector has a zero, NaN, or infinite norm
*/
boolean isCodirectionalTo(V v);
}
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,18 @@ public double angle(final Vector1D v) {
return (sig1 == sig2) ? 0.0 : Math.PI;
}


/**
* {@inheritDoc}
*/
@Override public boolean isCodirectionalTo(Vector1D v) {
// validate the norm values
getCheckedNorm();
v.getCheckedNorm();
return v.x / x > 0.0;
}


/** Convenience method to apply a function to this vector. This
* can be used to transform the vector inline with other methods.
* @param fn the function to apply
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.commons.geometry.euclidean.EuclideanVectorSum;
import org.apache.commons.geometry.euclidean.MultiDimensionalEuclideanVector;
import org.apache.commons.geometry.euclidean.internal.Vectors;
import org.apache.commons.geometry.euclidean.twod.Vector2D;
import org.apache.commons.numbers.core.Precision;

/** This class represents vectors and points in three-dimensional Euclidean space.
Expand Down Expand Up @@ -320,6 +321,28 @@ public double angle(final Vector3D v) {
return Math.acos(dot / normProduct);
}


/**
* {@inheritDoc}
*/
@Override public boolean isCodirectionalTo(Vector3D v) {
// validate the norm values
double magnitudeOfThis = getCheckedNorm();
double magnitudeOfV = v.getCheckedNorm();
// Handle zero vectors: consider any vector as codirectional to a zero vector
if ((x == 0 && y == 0 && z == 0) || (v.x == 0 && v.y == 0 && v.z == 0)) {
return true;
}

// If the ratios are equal, the vectors are codirectional.
double ratioX = x / v.x;
double ratioY = y / v.y;
double ratioZ = z / v.z;
// use a tolerance due to floating point inaccuracies
return Math.abs(ratioX - ratioY) < 0.000001 && Math.abs(ratioY - ratioZ) < 0.000001;
}


/** {@inheritDoc} */
@Override
public Vector3D project(final Vector3D base) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,26 @@ public double angle(final Vector2D v) {
return Math.acos(dot / normProduct);
}


/**
* {@inheritDoc}
*/
@Override public boolean isCodirectionalTo(Vector2D v) {
// validate the norm values
double magnitudeOfThis = getCheckedNorm();
double magnitudeOfV = v.getCheckedNorm();
// Handle zero vectors: consider any vector as codirectional to a zero vector
if ((x == 0 && y == 0) || (v.x == 0 && v.y == 0)) {
return true;
}

// If the ratios are equal, the vectors are codirectional.
double ratio = x / v.x;
// use a tolerance due to floating point inaccuracies
return Math.abs(ratio - (y / v.y)) < 0.000001;
}


/** {@inheritDoc} */
@Override
public Vector2D project(final Vector2D base) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,21 @@ void testUnitFactoryOptimization() {
Assertions.assertSame(v, v.normalize());
}

@Test
void testIsCodirectionalTo() {
final Vector1D v1 = Vector1D.of(1);
final Vector1D v2 = Vector1D.of(4);
Assertions.assertTrue(v1.isCodirectionalTo(v2));
Assertions.assertTrue(v2.isCodirectionalTo(v1));

final Vector1D v3 = Vector1D.of(-1);
final Vector1D v4 = Vector1D.of(-4);
Assertions.assertTrue(v3.isCodirectionalTo(v4));
Assertions.assertTrue(v3.isCodirectionalTo(v4));

Assertions.assertFalse(v1.isCodirectionalTo(v3));
}

private void checkVector(final Vector1D v, final double x) {
Assertions.assertEquals(x, v.getX(), TEST_TOLERANCE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import org.apache.commons.geometry.core.GeometryTestUtils;
import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
import org.apache.commons.geometry.euclidean.oned.Vector1D;
import org.apache.commons.numbers.angle.Angle;
import org.apache.commons.numbers.core.Precision;
import org.apache.commons.rng.UniformRandomProvider;
Expand Down Expand Up @@ -1368,6 +1369,27 @@ void testUnitFactoryOptimization() {
Assertions.assertSame(v, v.normalize());
}

@Test
void testIsCodirectionalTo() {
final Vector3D v1 = Vector3D.of(2, 2, 2);
final Vector3D v2 = Vector3D.of(1, 1, 1);
final Vector3D v3 = Vector3D.of(-2, -2, -2);
final Vector3D v4 = Vector3D.of(2, -2, 2);

// Test codirectional vectors (same direction)
Assertions.assertTrue(v1.isCodirectionalTo(v2));
Assertions.assertTrue(v2.isCodirectionalTo(v1));

// Test codirectional vectors (opposite direction)
Assertions.assertTrue(v1.isCodirectionalTo(v3));
Assertions.assertTrue(v3.isCodirectionalTo(v1));

// Test non-codirectional vectors
Assertions.assertFalse(v1.isCodirectionalTo(v4));
Assertions.assertFalse(v4.isCodirectionalTo(v1));

}

private void checkVector(final Vector3D v, final double x, final double y, final double z) {
Assertions.assertEquals(x, v.getX(), EPS);
Assertions.assertEquals(y, v.getY(), EPS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import org.apache.commons.geometry.core.GeometryTestUtils;
import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
import org.apache.commons.geometry.euclidean.oned.Vector1D;
import org.apache.commons.numbers.angle.Angle;
import org.apache.commons.numbers.core.Precision;
import org.junit.jupiter.api.Assertions;
Expand Down Expand Up @@ -1169,6 +1170,26 @@ void testUnitFactoryOptimization() {
Assertions.assertSame(v, v.normalize());
}

@Test
void testIsCodirectionalTo() {
final Vector2D v1 = Vector2D.of(2, 2);
final Vector2D v2 = Vector2D.of(1, 1);
final Vector2D v3 = Vector2D.of(-2, -2);
final Vector2D v4 = Vector2D.of(2, -2);

// Test codirectional vectors (same direction)
Assertions.assertTrue(v1.isCodirectionalTo(v2));
Assertions.assertTrue(v2.isCodirectionalTo(v1));

// Test codirectional vectors (opposite direction)
Assertions.assertTrue(v1.isCodirectionalTo(v3));
Assertions.assertTrue(v3.isCodirectionalTo(v1));

// Test non-codirectional vectors
Assertions.assertFalse(v1.isCodirectionalTo(v4));
Assertions.assertFalse(v4.isCodirectionalTo(v1));
}

private void checkVector(final Vector2D v, final double x, final double y) {
checkVector(v, x, y, EPS);
}
Expand Down
Loading