lcsim/test/org/lcsim/util/swim
diff -N HelixTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ HelixTest.java 18 Aug 2005 15:24:04 -0000 1.1
@@ -0,0 +1,114 @@
+package org.lcsim.util.swim;
+
+import hep.aida.ICloud2D;
+import junit.framework.*;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import java.io.IOException;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ *
+ * @author tonyj
+ * @version $Id: HelixTest.java,v 1.1 2005/08/18 15:24:04 tonyj Exp $
+ */
+public class HelixTest extends TestCase
+{
+
+ public HelixTest(String testName)
+ {
+ super(testName);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(HelixTest.class);
+ }
+
+ public void testCircle()
+ {
+ Hep3Vector origin = new BasicHep3Vector(1,0,0);
+ double radius = -1;
+ double phi = Math.PI/2;
+ double lambda = 0;
+ Helix circle = new Helix(origin,radius,phi,lambda);
+
+ assertEquals(origin, circle.getPointAtDistance(0));
+ assertEquals(origin, circle.getPointAtDistance(radius*Math.PI*2));
+ assertEquals(new BasicHep3Vector(-1,0,0), circle.getPointAtDistance(radius*Math.PI));
+
+ assertTrue(Double.isInfinite(circle.getDistanceToZPlane(1)));
+ assertTrue(Double.isNaN(circle.getDistanceToInfiniteCylinder(2)));
+ assertTrue(Double.isNaN(circle.getDistanceToInfiniteCylinder(0)));
+ assertEquals(0,circle.getDistanceToInfiniteCylinder(1),1e-14);
+ }
+ public void testCircle2()
+ {
+ Hep3Vector origin = new BasicHep3Vector(0,0,0);
+ double radius = 1;
+ double phi = Math.PI/2;
+ double lambda = 0;
+ Helix circle = new Helix(origin,radius,phi,lambda);
+
+ assertEquals(origin, circle.getPointAtDistance(0));
+ assertEquals(origin, circle.getPointAtDistance(radius*Math.PI*2));
+ assertEquals(new BasicHep3Vector(2,0,0), circle.getPointAtDistance(radius*Math.PI));
+
+ assertTrue(Double.isInfinite(circle.getDistanceToZPlane(1)));
+ assertTrue(Double.isNaN(circle.getDistanceToInfiniteCylinder(3*radius)));
+ assertEquals(radius*Math.PI,circle.getDistanceToInfiniteCylinder(2*radius),1e-14);
+ assertEquals(0,circle.getDistanceToInfiniteCylinder(0),1e-14);
+ }
+ public void testHelix()
+ {
+ Hep3Vector origin = new BasicHep3Vector(0,0,0);
+ double radius = 1;
+ double phi = Math.PI/2;
+ double lambda = Math.PI/4;
+ Helix helix = new Helix(origin,radius,phi,lambda);
+
+ assertEquals(origin, helix.getPointAtDistance(0));
+ double d = radius*Math.PI*2*Math.sqrt(2);
+ assertEquals(new BasicHep3Vector(0,0,Math.PI*2), helix.getPointAtDistance(d));
+ assertEquals(new BasicHep3Vector(2,0,Math.PI), helix.getPointAtDistance(d/2));
+
+ assertEquals(d/2,helix.getDistanceToZPlane(Math.PI));
+ assertEquals(d,helix.getDistanceToZPlane(Math.PI*2));
+ assertTrue(Double.isNaN(helix.getDistanceToInfiniteCylinder(3*radius)));
+ assertEquals(d/2,helix.getDistanceToInfiniteCylinder(2*radius),1e-14);
+ assertEquals(0,helix.getDistanceToInfiniteCylinder(0),1e-14);
+ }
+ public void testHelix2() throws IOException
+ {
+ Hep3Vector origin = new BasicHep3Vector(0,0,0);
+ double radius = 1;
+ double phi = Math.PI/2;
+ double lambda = Math.PI/4;
+ Helix helix = new Helix(origin,radius,phi,lambda);
+
+ double d = radius*Math.PI*2*Math.sqrt(2);
+
+ AIDA aida = AIDA.defaultInstance();
+ ICloud2D xy = aida.cloud2D("xy");
+ ICloud2D rz = aida.cloud2D("rz");
+ for (int i=0; i<100; i++)
+ {
+ double alpha = i*d/100;
+ Hep3Vector point = helix.getPointAtDistance(alpha);
+ xy.fill(point.x(),point.y());
+ double r = Math.sqrt(point.x()*point.x()+point.y()*point.y());
+ rz.fill(r,point.z());
+ }
+ assertEquals(1,xy.meanX(),1e-14);
+ assertEquals(0,xy.meanY(),1e-14);
+ assertEquals(Math.sqrt(2)/2,xy.rmsX(),1e-14);
+ assertEquals(Math.sqrt(2)/2,xy.rmsY(),1e-14);
+ aida.saveAs("helix.aida");
+ }
+ private void assertEquals(Hep3Vector v1, Hep3Vector v2)
+ {
+ assertEquals(v1.x(),v2.x(), 1e-14);
+ assertEquals(v1.y(),v2.y(), 1e-14);
+ assertEquals(v1.z(),v2.z(), 1e-14);
+ }
+}
lcsim/src/org/lcsim/util/swim
diff -N Helix.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Helix.java 18 Aug 2005 15:24:04 -0000 1.1
@@ -0,0 +1,80 @@
+package org.lcsim.util.swim;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * This class represents a helix with its axis aligned along Z.
+ * All quantities in this class are dimensionless. It has no dependencies
+ * except for Hep3Vector (which could easily be removed).
+ * @author tonyj
+ * @version $Id: Helix.java,v 1.1 2005/08/18 15:24:04 tonyj Exp $
+ */
+public class Helix
+{
+ /** Creates a new instance of Helix.
+ * @param origin A point on the helix
+ * @param radius The signed radius of curvature of the helix
+ * @param phi The azimuthal angle of the helix in x-y plane w/rt x-axis at the origin
+ * @param lambda The dip angle w/rt x-y plane
+ */
+ public Helix(Hep3Vector origin, double radius, double phi, double lambda)
+ {
+ if (Math.abs(lambda) >= Math.PI/2) throw new IllegalArgumentException("lambda="+lambda);
+ this.origin = origin;
+ this.radius = radius;
+ this.phi = phi;
+
+ // Calculate some useful quantities
+
+ cosLambda = Math.cos(lambda);
+ sinLambda = Math.sin(lambda);
+ xCenter = origin.x() + radius*Math.sin(phi);
+ yCenter = origin.y() - radius*Math.cos(phi);
+ phiToCenter = Math.atan2(yCenter,xCenter);
+ radiusOfCenter = Math.sqrt(xCenter*xCenter + yCenter*yCenter);
+ }
+ /**
+ * Gets a point after traveling distance alpha from the origin along the helix
+ */
+ public Hep3Vector getPointAtDistance(double alpha)
+ {
+ double darg = alpha*cosLambda/radius - phi;
+ double x = xCenter + radius*Math.sin( darg );
+ double y = yCenter + radius*Math.cos( darg );
+ double z = origin.z() + alpha*sinLambda;
+ return new BasicHep3Vector(x,y,z);
+ }
+
+ /**
+ * Calculate the distance along the helix to reach a given Z plane.
+ * Note distance may be negative.
+ *
+ */
+ public double getDistanceToZPlane(double z)
+ {
+ return (z - origin.z())/sinLambda;
+ }
+
+ /**
+ * Calculates the distance at which the helix first reaches radius R.
+ * Returns Double.NaN if the helix does not intercept the cylinder.
+ */
+
+ public double getDistanceToInfiniteCylinder(double r)
+ {
+ double darg = r*r/(2.*radius*radiusOfCenter) - radiusOfCenter/(2.*radius) - radius/(2.*radiusOfCenter);
+ double diff = Math.asin(darg) + phi - phiToCenter;
+ return (radius/cosLambda)*diff;
+ }
+
+ private Hep3Vector origin;
+ private double xCenter;
+ private double yCenter;
+ private double radius;
+ private double sinLambda;
+ private double cosLambda;
+ private double phi;
+ private double phiToCenter;
+ private double radiusOfCenter;
+}