Commit in lcsim on MAIN
test/org/lcsim/util/swim/HelixTest.java+114added 1.1
src/org/lcsim/util/swim/Helix.java+80added 1.1
+194
2 added files
A new Helix implementation. This is phase I of refactoring HelixSwim, next HelixSwim will be refactored to use the HelixClass underneath.

lcsim/test/org/lcsim/util/swim
HelixTest.java added at 1.1
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
Helix.java added at 1.1
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;
+}
CVSspam 0.2.8