Skip to content

Commit

Permalink
Test for 3 colinear points
Browse files Browse the repository at this point in the history
  • Loading branch information
gilleain authored and egonw committed Aug 1, 2010
1 parent bb38d10 commit 01ae3fc
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 6 deletions.
40 changes: 34 additions & 6 deletions src/main/org/openscience/cdk/tools/StereoTool.java
Expand Up @@ -42,6 +42,11 @@ public enum SquarePlanarShape { U_SHAPE, FOUR_SHAPE, Z_SHAPE }
*/
public static final double MAX_AXIS_ANGLE = 0.95;

/**
* The maximum tolerance for the normal calculated during colinearity.
*/
public static final double MIN_COLINEAR_NORMAL = 0.05;

/**
* Checks these four atoms for square planarity.
*
Expand Down Expand Up @@ -193,6 +198,26 @@ private static boolean isDiaxial(Point3d pointA, Point3d pointB,
// -0.95f about 172 degrees
return vAC.dot(vBD) < maxAngle;
}

/**
* Checks the three supplied points to see if they fall on the same line.
* It does this by finding the normal to an arbitrary pair of lines between
* the points (in fact, A-B and A-C) and checking that its length is 0.
*
* @param ptA
* @param ptB
* @param ptC
* @return
*/
public static boolean colinear(Point3d ptA, Point3d ptB, Point3d ptC) {
Vector3d vectorAB = new Vector3d();
Vector3d vectorAC = new Vector3d();
Vector3d normal = new Vector3d();

StereoTool.getRawNormal(ptA, ptB, ptC, normal, vectorAB, vectorAC);
double baCrossACLen = normal.length();
return baCrossACLen < StereoTool.MIN_COLINEAR_NORMAL;
}

/**
* Given a normalized normal for a plane, any point in that plane, and
Expand Down Expand Up @@ -232,9 +257,12 @@ private static void getPlaneNormals(
Vector3d vectorE = new Vector3d();

// the normals (normalA, normalB, normalC) are calculated
StereoTool.getNormal(pointA, pointB, pointC, normalA, vectorD, vectorE);
StereoTool.getNormal(pointB, pointC, pointD, normalB, vectorD, vectorE);
StereoTool.getNormal(pointC, pointD, pointA, normalC, vectorD, vectorE);
StereoTool.getRawNormal(pointA, pointB, pointC, normalA, vectorD, vectorE);
StereoTool.getRawNormal(pointB, pointC, pointD, normalB, vectorD, vectorE);
StereoTool.getRawNormal(pointC, pointD, pointA, normalC, vectorD, vectorE);
normalA.normalize();
normalB.normalize();
normalC.normalize();
}

/**
Expand All @@ -254,19 +282,19 @@ public static Vector3d getNormal(Point3d ptA, Point3d ptB, Point3d ptC) {
Vector3d vectorAB = new Vector3d();
Vector3d vectorAC = new Vector3d();
Vector3d normal = new Vector3d();
StereoTool.getNormal(ptA, ptB, ptC, normal, vectorAB, vectorAC);
StereoTool.getRawNormal(ptA, ptB, ptC, normal, vectorAB, vectorAC);
normal.normalize();
return normal;
}

private static void getNormal(Point3d ptA, Point3d ptB, Point3d ptC,
private static void getRawNormal(Point3d ptA, Point3d ptB, Point3d ptC,
Vector3d normal, Vector3d vcAB, Vector3d vcAC) {
// make A->B and A->C
vcAB.sub(ptB, ptA);
vcAC.sub(ptC, ptA);

// make the normal to this
normal.cross(vcAB, vcAC);
normal.normalize();
}

}
26 changes: 26 additions & 0 deletions src/test/org/openscience/cdk/tools/StereoToolTest.java
Expand Up @@ -89,5 +89,31 @@ public void tetrahedralMinusAtomsTest() {
StereoTool.getHandedness(baseA, baseB, baseC, negativeApex);
Assert.assertEquals(TetrahedralSign.MINUS, tetSign);
}

@Test
public void colinearTestWithColinearPoints() {
Point3d pointA = new Point3d(1, 1, 1);
Point3d pointB = new Point3d(2, 2, 2);
Point3d pointC = new Point3d(3, 3, 3);

Assert.assertTrue(StereoTool.colinear(pointA, pointB, pointC));
}

@Test
public void colinearTestWithNearlyColinearPoints() {
Point3d pointA = new Point3d(1, 1, 1);
Point3d pointB = new Point3d(2, 2.001, 2);
Point3d pointC = new Point3d(3, 3, 3);

Assert.assertTrue(StereoTool.colinear(pointA, pointB, pointC));
}

@Test
public void colinearTestWithNonColinearPoints() {
Point3d pointA = new Point3d(1, 1, 1);
Point3d pointB = new Point3d(2, 3, 2);
Point3d pointC = new Point3d(3, 3, 3);

Assert.assertFalse(StereoTool.colinear(pointA, pointB, pointC));
}
}

0 comments on commit 01ae3fc

Please sign in to comment.