Commit in lcsim/src/org/lcsim/contrib/onoprien/crux/swim on MAIN
AbstractIntersection.java+63added 1.1
AbstractSurface.java+22added 1.1
Intersection.java+72added 1.1
IntersectionMultiple.java+69added 1.1
IntersectionNone.java+50added 1.1
IntersectionPeriodic.java+177added 1.1
IntersectionPeriodicBound.java+115added 1.1
IntersectionSingle.java+80added 1.1
ParCovMatrix.java+56added 1.1
ParVector.java+49added 1.1
Poca.java+59added 1.1
PocaXY.java+58added 1.1
Surface.java+18added 1.1
ZCylinder.java+56added 1.1
ZDisk.java+57added 1.1
ZPlane.java+42added 1.1
AbstractTrajectory.java+32-1291.1 -> 1.2
Helix.java+267-571.1 -> 1.2
Line.java+152-761.1 -> 1.2
Trajectory.java+37-701.1 -> 1.2
+1531-332
16 added + 4 modified, total 20 files
Update to swim package (untested)

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
AbstractIntersection.java added at 1.1
diff -N AbstractIntersection.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ AbstractIntersection.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,63 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import hep.physics.vec.Hep3Vector;
+import org.lcsim.units.clhep.SystemOfUnits;
+
+/**
+ * Abstract class that provides a skeletal implementation of the {@link Intersection}
+ * interface to minimize the effort required to implement this interface.
+ *
+ * @author D. Onoprienko
+ * @version $Id: AbstractIntersection.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+abstract public class AbstractIntersection implements Intersection {
+  
+  /**
+   * Precision with which the path length to an intersection is calculated.
+   * <i>Intersections closer to each other than this distance will be merged.
+   * <b>This behavior is currently disabled.</b></i>
+   * Default value: 0.1 micrometer.
+   */
+  public static double pathLengthTolerance = .1 * SystemOfUnits.micrometer;
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public AbstractIntersection() {
+  }
+  
+  public AbstractIntersection(Trajectory trajectory, Surface surface) {
+    _trajectory = trajectory;
+    _surface = surface;
+  }
+  
+// -- Stepping through intersection points :  ----------------------------------
+  
+  public void stepForward() {
+    step(1);
+  }
+  
+  public void stepBack() {
+    step(-1);
+  }
+
+// -- Trajectory parameters at the next intersection point :  ------------------
+  
+  public Hep3Vector getPoint() {
+    return _trajectory.getPoint(getPathLength());
+  }
+  
+  public Hep3Vector getDirection() {
+    return _trajectory.getDirection(getPathLength());
+  }
+
+// -- Access to intersecting objects :  ----------------------------------------
+  
+  public Trajectory getTrajectory() {return _trajectory;}
+  
+  public Surface getSurface() {return _surface;}
+
+// -- Private parts :  ---------------------------------------------------------
+  
+  protected Trajectory _trajectory;
+  protected Surface _surface;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
AbstractSurface.java added at 1.1
diff -N AbstractSurface.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ AbstractSurface.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,22 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+/**
+ * Abstract class that provides a skeletal implementation of the {@link Surface}
+ * interface to minimize the effort required to implement this interface.
+ *
+ * @author D. Onoprienko
+ * @version $Id: AbstractSurface.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+abstract public class AbstractSurface implements Surface {
+  
+  /**
+   * Default implementation provided by this class throws <tt>UnsupportedOperationException</tt>
+   * with a diagnostic message. Concrete subclasses must override to return intersection 
+   * of the specified trajectory with this surface.
+   */
+  public Intersection intersect(Trajectory trajectory) {
+    throw new UnsupportedOperationException("No idea how to find intersection of " 
+      + this.getClass().getName() + " with " + trajectory.getClass().getName() + " - please implement");
+  }
+  
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
Intersection.java added at 1.1
diff -N Intersection.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Intersection.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,72 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import java.util.NoSuchElementException;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * An intersection between a trajectory and a surface.
+ * <p>
+ * The intersection consists of zero or more intersection points ordered along the
+ * trajectory direction, and the <tt>Intersection</tt>
+ * object provides a way to iterate over them. Each instance of this class has a cursor 
+ * that is always positioned between two intersection points. In an <tt>Intersection</tt>
+ * consisting of <tt>n</tt> points, there are <tt>n+1</tt> valid cursor positions corresponding
+ * to <tt>n+1</tt> gaps between points, including the gap before the first point and the gap 
+ * after the last point. The cursor can be moved by calling <tt>step(int)</tt>, 
+ * <tt>stepForward()</tt>, and <tt>stepBack()</tt> methods. <tt>hasPrevious()</tt> and
+ * <tt>hasNext()</tt> methods check whether thare is an intersection point upstream and
+ * downstream from the cursor. <tt>getPathLength()</tt>, <tt>getPoint()</tt>, and 
+ * <tt>getDirection()</tt> methods return trajectory parameters at the point downstream
+ * from the cursor. An attempt to move the cursor beyond the ends of the point list, or to
+ * obtain trajectory parameters when the cursor is downstream from the last intersection point,
+ * throws {@link NoSuchElementException}.
+ * <p>
+ * When the <tt>Intersection</tt> is first created, its cursor is positioned before the first 
+ * intersection point downstream (along the trajectory direction) from the trajectory origin.
+ * Therefore, an immediate call to <tt>getPathLength()</tt> will return the path length to
+ * that point, or throw <tt>NoSuchElementException</tt> if there are no intersections downstream
+ * from the origin.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Intersection.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public interface Intersection {
+  
+// -- Number of intersection points :  -----------------------------------------
+  
+  /**
+   * Returns the number of intersection points.
+   * If the number is infinite, returns <tt>-1</tt>.
+   */
+  public int size();
+  
+// -- Stepping through intersection points :  ----------------------------------
+  
+  public void step(int steps);
+  
+  public void stepForward();
+  
+  public void stepBack();
+  
+  public boolean hasNext();
+  
+  public boolean hasPrevious();
+  
+// -- Trajectory parameters at the next intersection point :  ------------------
+  
+  public double getPathLength();
+  
+  public Hep3Vector getPoint();
+  
+  public Hep3Vector getDirection();
+  
+// -- Access to intersecting objects :  ----------------------------------------
+  
+  /** Returns the trajectory this intersection belongs to. */
+  public Trajectory getTrajectory();
+  
+  /** Returns the surface this intersection belongs to. */
+  public Surface getSurface();
+
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
IntersectionMultiple.java added at 1.1
diff -N IntersectionMultiple.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ IntersectionMultiple.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,69 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import java.util.*;
+
+/**
+ * An implementation of {@link Intersection} interface suitable for use when there is
+ * a finite number of intersection points, and their locations along the path length of 
+ * the trajectory need to be explicitly specified to the constructor.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionMultiple.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class IntersectionMultiple extends AbstractIntersection {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  protected IntersectionMultiple() {
+    super();
+  }
+  
+  public IntersectionMultiple(double[] pathLengths, Trajectory trajectory, Surface surface) {
+    super(trajectory, surface);
+    _next = 0;
+    Arrays.sort(pathLengths);
+    _path = pathLengths;
+    while (_next < pathLengths.length && pathLengths[_next] <= 0.) _next++;
+  }
+  
+// -- Number of intersection points :  -----------------------------------------
+  
+  public int size() {return _path.length;}
+  
+// -- Stepping through intersection points :  ----------------------------------
+  
+  public void step(int steps) {
+    int i = _next + steps;
+    if (i < 0 || i > _path.length) {
+      throw new NoSuchElementException();
+    } else {
+      _next = i;
+    }
+  }
+  
+  public boolean hasNext() {
+    return _next < _path.length;
+  }
+  
+  public boolean hasPrevious() {
+    return _next > 0;
+  }
+
+  
+// -- Trajectory parameters at the next intersection point :  ------------------
+  
+  public double getPathLength() {
+    if (_next < _path.length) {
+      return _path[_next];
+    } else {
+      throw new NoSuchElementException();
+    }
+  }
+
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  protected double[] _path;
+  protected int _next;
+  
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
IntersectionNone.java added at 1.1
diff -N IntersectionNone.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ IntersectionNone.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,50 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import java.util.NoSuchElementException;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * An implementation of {@link Intersection} interface suitable for use when the trajectory
+ * and the surface have no intersection points.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionNone.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class IntersectionNone extends AbstractIntersection {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public IntersectionNone() {
+    super();
+  }
+  
+  public IntersectionNone(Trajectory trajectory, Surface surface) {
+    super(trajectory, surface);
+  }
+  
+// -- Number of intersection points :  -----------------------------------------
+  
+  public int size() {return 0;}
+  
+// -- Stepping through intersection points :  ----------------------------------
+  
+  public void step(int steps) {throw new NoSuchElementException();}
+  
+  public void stepForward() {throw new NoSuchElementException();}
+  
+  public void stepBack() {throw new NoSuchElementException();}
+  
+  public boolean hasNext() {return false;}
+  
+  public boolean hasPrevious() {return false;}
+  
+// -- Trajectory parameters at the next intersection point :  ------------------
+  
+  public double getPathLength() {throw new NoSuchElementException();}
+  
+  public Hep3Vector getPoint() {throw new NoSuchElementException();}
+  
+  public Hep3Vector getDirection() {throw new NoSuchElementException();}
+  
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
IntersectionPeriodic.java added at 1.1
diff -N IntersectionPeriodic.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ IntersectionPeriodic.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,177 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import java.util.*;
+
+/**
+ * Specialized implementation of {@link Intersection} interface suitable for use when
+ * locations of intersection points are periodic along the path length of the trajectory.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionPeriodic.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class IntersectionPeriodic extends AbstractIntersection {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  /** Default constructor for use by superclasses. */
+  protected IntersectionPeriodic() {
+    super();
+  }
+  
+  /** Empty constructor for use by superclasses. */
+  protected IntersectionPeriodic(Trajectory trajectory, Surface surface) {
+    super(trajectory, surface);
+  }
+  
+  /**
+   * Main constructor.
+   *
+   * @param fast  If <tt>true</tt>, the <tt>pathLengths</tt> array will be used "as is" 
+   *              and owned by this <tt>Intersection</tt> object. If <tt>false</tt>, the 
+   *              array will be copied, ordered, and its elements will be shifted to make 
+   *              sure they do not differ by more then <tt>period</tt>.
+   * @param pathLengths An array containing a set of unique path lengths to intersection points
+   *                    (those that cannot be obtained from each other by shifting by several periods).
+   */
+  public IntersectionPeriodic(boolean fast, double[] pathLengths, double period, Trajectory trajectory, Surface surface) {
+    super(trajectory, surface);
+    _pathPeriod = period;
+    if (fast) {
+      _path = pathLengths;
+    } else {
+      int n = pathLengths.length;
+      _path = new double[n];
+      double sMin = pathLengths[0];
+      for (int i=0; i<n; i++) {
+        _path[i] = pathLengths[i];
+        if (pathLengths[i] < sMin) sMin = pathLengths[i];
+      }
+      for (int i=0; i<n; i++) {
+        int iPeriod = (int) Math.floor((_path[i]-sMin) / _pathPeriod);
+        _path[i] = _path[i] - iPeriod * _pathPeriod;
+      }
+      Arrays.sort(_path);
+    }
+    _index = new Index();
+    _index.iSetBeforeGT(0.);
+  }
+  
+// -- Number of intersection points :  -----------------------------------------
+  
+  public int size() {return -1;}
+  
+// -- Stepping through intersection points :  ----------------------------------
+  
+  public void step(int steps) {
+    _index.iStep(steps);
+  }
+  
+  public void stepForward() {
+    _index.iStepForward();
+  }
+  
+  public void stepBack() {
+    _index.iStepBack();
+  }
+  
+  public boolean hasNext() {return true;}
+  
+  public boolean hasPrevious() {return true;}
+  
+// -- Trajectory parameters at the next intersection point :  ------------------
+  
+  public double getPathLength() {
+    return _index.iGetPathLength();
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  protected double[] _path;
+  protected double _pathPeriod;
+  protected Index _index;
+  
+// -- Index class :  -----------------------------------------------------------
+
+  /** Class that represents a pointer to a particular intersection point. */
+  protected class Index implements Comparable<Index> {
+    
+    Index() {
+      iPeriod = 0;
+      iNext = 0;      
+    }
+    
+    Index(int period, int next) {
+      iPeriod = period;
+      iNext = next;
+    }
+    
+    Index(Index index) {
+      iPeriod = index.iPeriod;
+      iNext = index.iNext;
+    }
+    
+    public void iStep(int steps) {
+      int i = iNext + steps;
+      iPeriod += i / _path.length;
+      iNext = i % _path.length;
+      if (iNext < 0) {
+        iNext += _path.length;
+        iPeriod--;
+      }
+    }
+    
+    public void iStepForward() {
+      if (++iNext == _path.length) {
+        iNext = 0;
+        iPeriod++;
+      }
+    }
+    
+    public void iStepBack() {
+      if (--iNext < 0) {
+        iNext = _path.length - 1;
+        iPeriod--;
+      }
+    }
+    
+    public double iGetPathLength() {
+      return _path[iNext] + iPeriod * _pathPeriod;
+    }
+    
+    public int iSubtract(Index index) {
+      return (iPeriod - index.iPeriod) * _path.length + (iNext - index.iNext);
+    }
+    
+    public int compareTo(Index index) {
+      return (iPeriod == index.iPeriod) ? (iNext - index.iNext) : (iPeriod - index.iPeriod) ;
+    }
+    
+    /**
+     * Sets the index to point to the first intersection point with the path length 
+     * greater than the one specified by the argument.
+     */
+    public void iSetBeforeGT(double s) {
+      iPeriod = (int) (Math.ceil( (s - _path[_path.length-1]) / _pathPeriod) );
+      iNext = 0;
+      while (iGetPathLength() <= s) {
+        iStepForward();
+      }
+    }
+
+    /**
+     * Sets the index to point to the first intersection point with the path length 
+     * greater or equal to the one specified by the argument.
+     */
+    public void iSetBeforeGE(double s) {
+      iPeriod = (int) (Math.ceil( (s - _path[_path.length-1]) / _pathPeriod) );
+      iNext = 0;
+      while (iGetPathLength() < s) {
+        iStepForward();
+      }
+    }
+    
+    int iPeriod;
+    int iNext;
+  }
+  
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
IntersectionPeriodicBound.java added at 1.1
diff -N IntersectionPeriodicBound.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ IntersectionPeriodicBound.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,115 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import java.util.*;
+
+/**
+ * Specialized implementation of {@link Intersection} interface suitable for use when
+ * locations of intersection points are periodic along the path length of the trajectory,
+ * but bounded to certain path length interval.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionPeriodicBound.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class IntersectionPeriodicBound extends IntersectionPeriodic {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  /** Default constructor for use by superclasses. */
+  protected IntersectionPeriodicBound() {
+    super();
+  }
+  
+  /** Empty constructor for use by superclasses. */
+  protected IntersectionPeriodicBound(Trajectory trajectory, Surface surface) {
+    super(trajectory, surface);
+  }
+  
+  /**
+   * Main constructor.
+   *
+   * @param fast  If <tt>true</tt>, the <tt>pathLengths</tt> array will be used "as is" 
+   *              and owned by this <tt>Intersection</tt> object. If <tt>false</tt>, the 
+   *              array will be copied, ordered, and its elements will be shifted to make 
+   *              sure they do not differ by more then <tt>period</tt>. The order of bounds will
+   *              also be checked.
+   * @param pathLengths An array containing a set of unique path lengths to intersection points
+   *                    (those that cannot be obtained from each other by shifting by several periods).
+   */
+  public IntersectionPeriodicBound(boolean fast, double pathLengthMin, double pathLengthMax, 
+          double[] pathLengths, double period, Trajectory trajectory, Surface surface) {
+    super(fast, pathLengths, period, trajectory, surface);
+    if (pathLengthMin < pathLengthMax) {
+      init(pathLengthMin, pathLengthMax);
+    } else {
+      init(pathLengthMax, pathLengthMin);
+    }
+  }
+  
+  protected void init(double pathLengthMin, double pathLengthMax) {
+    _min = new Index();
+    _min.iSetBeforeGT(pathLengthMin);
+    _max = new Index();
+    _max.iSetBeforeGE(pathLengthMax);
+    if (_index.compareTo(_min) < 0) {
+      _index = new Index(_min);
+    } else if (_index.compareTo(_max) > 0) {
+      _index = new Index(_max);
+    }    
+  }
+  
+// -- Number of intersection points :  -----------------------------------------
+  
+  public int size() {
+    return _max.iSubtract(_min);
+  }
+  
+// -- Stepping through intersection points :  ----------------------------------
+  
+  public void step(int steps) {
+    Index newIndex = new Index(_index);
+    newIndex.iStep(steps);
+    if (newIndex.compareTo(_min) < 0 || newIndex.compareTo(_max) > 0) {
+      throw new NoSuchElementException();
+    } else {
+      _index = newIndex;
+    }
+  }
+  
+  public void stepForward() {
+    if (hasNext()) {
+      _index.iStepForward();
+    } else {
+      throw new NoSuchElementException();
+    }
+  }
+  
+  public void stepBack() {
+    if (hasPrevious()) {
+      _index.iStepBack();
+    } else {
+      throw new NoSuchElementException();
+    }
+  }
+  
+  public boolean hasNext() {
+    return _index.compareTo(_max) < 0 ;
+  }
+  
+  public boolean hasPrevious() {
+    return _index.compareTo(_min) > 0 ;
+  }
+  
+// -- Trajectory parameters at the next intersection point :  ------------------
+  
+  public double getPathLength() {
+    if (hasNext()) {
+      return _index.iGetPathLength();
+    } else {
+      throw new NoSuchElementException();
+    }
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  protected Index _min, _max;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
IntersectionSingle.java added at 1.1
diff -N IntersectionSingle.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ IntersectionSingle.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,80 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import java.util.NoSuchElementException;
+
+/**
+ * An implementation of {@link Intersection} interface suitable for use when there
+ * is a single intersection point.
+ *
+ * @author D. Onoprienko
+ * @version $Id: IntersectionSingle.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class IntersectionSingle extends AbstractIntersection {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  protected IntersectionSingle() {
+    super();
+  }
+  
+  public IntersectionSingle(double pathLength, Trajectory trajectory, Surface surface) {
+    super(trajectory, surface);
+    _path = pathLength;
+    _hasNext = pathLength > 0.;
+  }
+
+  
+// -- Number of intersection points :  -----------------------------------------
+  
+  public int size() {return 1;}
+
+  
+// -- Stepping through intersection points :  ----------------------------------
+  
+  public void step(int steps) {
+    if (steps == 1) {
+      stepForward();
+    } else if (steps == -1) {
+      stepBack();
+    } else if (steps != 0) {
+      throw new NoSuchElementException();
+    }
+  }
+  
+  public void stepForward() {
+    if (_hasNext) {
+      _hasNext = false;
+    } else {
+      throw new NoSuchElementException();
+    }
+  }
+  
+  public void stepBack() {
+    if (_hasNext) {
+      throw new NoSuchElementException();
+    } else {
+      _hasNext = true;
+    }
+  }
+  
+  public boolean hasNext() {return _hasNext;}
+  
+  public boolean hasPrevious() {return ! _hasNext;}
+
+  
+// -- Trajectory parameters at the next intersection point :  ------------------
+  
+  public double getPathLength() {
+    if (_hasNext) {
+      return _path;
+    } else {
+      throw new NoSuchElementException();
+    }
+  }
+
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  protected double _path;
+  protected boolean _hasNext;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
ParCovMatrix.java added at 1.1
diff -N ParCovMatrix.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ParCovMatrix.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,56 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import hep.physics.matrix.SymmetricMatrix;
+
+/**
+ * An instance of this class represents a covariance matrix of parameters that define a trajectory,
+ * in a particular representation. The representation is described by enum that contains
+ * constants identifying the parameters (for example, {@link Helix} parameters can be
+ * described in {@link Helix.CRep} and {@link Helix.WRep} representations).
+ *
+ * @author D. Onoprienko
+ * @version $Id: ParCovMatrix.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class ParCovMatrix<T extends Enum<T>> extends SymmetricMatrix {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public ParCovMatrix(Class<T> representation) {
+    super(representation.getEnumConstants().length);
+    _rep = representation;
+  }
+  
+  public ParCovMatrix(Class<T> representation, double[] initialValues, boolean isLower) {
+    super(representation.getEnumConstants().length, initialValues, isLower);
+    _rep = representation;
+  }
+  
+  public ParCovMatrix(ParCovMatrix<T> covMatrix) {
+    super(covMatrix);
+    _rep = covMatrix._rep;
+  }
+  
+// -- Getters :  ---------------------------------------------------------------
+  
+  public double get(T parameter) {
+    return diagonal(parameter.ordinal());
+  }
+  
+  public double get(T parameter1, T parameter2) {
+    return e(parameter1.ordinal(), parameter2.ordinal());
+  }
+  
+// -- Setters :  ---------------------------------------------------------------
+  
+  public void set(T parameter, double value) {
+    setElement(parameter.ordinal(), parameter.ordinal(), value);
+  }
+  
+  public void set(T parameter1, T parameter2, double value) {
+    setElement(parameter1.ordinal(), parameter2.ordinal(), value);
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+
+  private Class<T> _rep;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
ParVector.java added at 1.1
diff -N ParVector.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ParVector.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,49 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+/**
+ * An instance of this class represents a vector of parameters that define a trajectory,
+ * in a particular representation. The representation is described by enum that contains
+ * constants identifying the parameters (for example, {@link Helix} parameters can be
+ * described in {@link Helix.CRep} and {@link Helix.WRep} representations).
+ *
+ * @author D. Onoprienko
+ * @version $Id: ParVector.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class ParVector<T extends Enum<T>> {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public ParVector(Class<T> representation) {
+    _rep = representation;
+    _pars = new double[_rep.getEnumConstants().length];
+  }
+
+  public ParVector(Class<T> representation, double... values) {
+    _rep = representation;
+    int n = _rep.getEnumConstants().length;
+    if (values.length != n) throw new IllegalArgumentException();
+    _pars = values;
+  }
+
+  public ParVector(ParVector parVector) {
+    _rep = parVector._rep;
+    _pars = (double[]) parVector._pars.clone();
+  }
+  
+// -- Getters :  ---------------------------------------------------------------
+  
+  public double get(T parameter) {
+    return _pars[parameter.ordinal()];
+  }
+  
+// -- Setters :  ---------------------------------------------------------------
+  
+  public void set(T parameter, double value) {
+    _pars[parameter.ordinal()] = value;
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  private Class<T> _rep;
+  private double[] _pars;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
Poca.java added at 1.1
diff -N Poca.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Poca.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,59 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+import org.lcsim.contrib.onoprien.crux.util.ConstHep3Vector;
+
+/**
+ * {@link Surface} that represents point of closest approach to the point supplied to
+ * its constructor.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Poca.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class Poca extends AbstractSurface {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public Poca(Hep3Vector point) {
+    if (point instanceof ConstHep3Vector) {
+      _point = (ConstHep3Vector) point;
+    } else {
+      _point = new ConstHep3Vector(point.v());
+    }
+  }
+  
+  public Poca(double[] point) {
+    _point = new ConstHep3Vector(point);
+  }
+  
+  public Poca(double x, double y, double z) {
+    _point = new ConstHep3Vector(x,y,z);
+  }
+  
+// -- Getters :  ---------------------------------------------------------------
+  
+  public ConstHep3Vector getPoint() {
+    return _point;
+  }
+  
+// -- Implementing Surface :  --------------------------------------------------
+  
+  /**
+   * Returns intersection of the specified trajectory with this surface.
+   */
+  public Intersection intersect(Trajectory trajectory) {
+    if (trajectory instanceof Line) {
+      return ((Line)trajectory).intersect(this);
+    } else if (trajectory instanceof Helix) {
+      return ((Helix)trajectory).intersect(this);
+    } else {
+      return super.intersect(trajectory);
+    }
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  private ConstHep3Vector _point;
+  
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
PocaXY.java added at 1.1
diff -N PocaXY.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ PocaXY.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,58 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+import org.lcsim.contrib.onoprien.crux.util.ConstHep3Vector;
+
+/**
+ * {@link Surface} that represents point of closest approach in XY plane to the 
+ * point supplied to its constructor.
+ *
+ * @author D. Onoprienko
+ * @version $Id: PocaXY.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class PocaXY extends AbstractSurface {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public PocaXY(Hep3Vector point) {
+    if (point instanceof ConstHep3Vector) {
+      _point = (ConstHep3Vector) point;
+    } else {
+      _point = new ConstHep3Vector(point.v());
+    }
+  }
+  
+  public PocaXY(double[] point) {
+    _point = new ConstHep3Vector(point);
+  }
+  
+  public PocaXY(double x, double y, double z) {
+    _point = new ConstHep3Vector(x,y,z);
+  }
+  
+// -- Getters :  ---------------------------------------------------------------
+  
+  public ConstHep3Vector getPoint() {
+    return _point;
+  }
+  
+// -- Implementing Surface :  --------------------------------------------------
+  
+  /**
+   * Returns intersection of the specified trajectory with this surface.
+   */
+  public Intersection intersect(Trajectory trajectory) {
+    if (trajectory instanceof Line) {
+      return ((Line)trajectory).intersect(this);
+    } else if (trajectory instanceof Helix) {
+      return ((Helix)trajectory).intersect(this);
+    } else {
+      return super.intersect(trajectory);
+    }
+  }
+
+// -- Private parts :  ---------------------------------------------------------
+  
+  private ConstHep3Vector _point;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
Surface.java added at 1.1
diff -N Surface.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Surface.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,18 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * A surface in space.
+ *
+ * @author D. Onoprienko
+ * @version $Id: Surface.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public interface Surface {
+  
+  /**
+   * Returns intersection of the specified trajectory with this surface.
+   */
+  public Intersection intersect(Trajectory trajectory);
+  
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
ZCylinder.java added at 1.1
diff -N ZCylinder.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ZCylinder.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,56 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import org.lcsim.contrib.onoprien.crux.util.ConstHep3Vector;
+
+/**
+ * {@link Surface} that represents a bounded cylinder parallel to and centered at Z axis.
+ * This surface is characterized by radius, low Z bound, and high Z bound.
+ *
+ * @author D. Onoprienko
+ * @version $Id: ZCylinder.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class ZCylinder extends AbstractSurface {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public ZCylinder(double radius, double zMin, double zMax) {
+  }
+  
+// -- Getters :  ---------------------------------------------------------------
+  
+  /** Returns radius of this cylinder. */
+  public double getRadius() {
+    return _r;
+  }
+  
+  /** Returns minimum Z of this cylinder. */
+  public double getMinZ() {
+    return _zMin;
+  }
+  
+  /** Returns minimum Z of this cylinder. */
+  public double getMaxZ() {
+    return _zMax;
+  }
+  
+// -- Implementing Surface :  --------------------------------------------------
+  
+  /**
+   * Returns intersection of the specified trajectory with this surface.
+   */
+  public Intersection intersect(Trajectory trajectory) {
+    if (trajectory instanceof Line) {
+      return ((Line)trajectory).intersect(this);
+    } else if (trajectory instanceof Helix) {
+      return ((Helix)trajectory).intersect(this);
+    } else {
+      return super.intersect(trajectory);
+    }
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  double _r;
+  double _zMin, _zMax;
+  
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
ZDisk.java added at 1.1
diff -N ZDisk.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ZDisk.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,57 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+import hep.physics.vec.Hep3Vector;
+
+/**
+ * {@link Surface} that represents a disk centered around Z axis and perpendicular to it.
+ *
+ * @author D. Onoprienko
+ * @version $Id: ZDisk.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class ZDisk extends AbstractSurface {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public ZDisk(double z, double radiusMin, double radiusMax) {
+    _z = z;
+    _rMin2 = radiusMin * radiusMin;
+    _rMax2 = radiusMax * radiusMax;
+  }
+  
+// -- Getters :  ---------------------------------------------------------------
+  
+  /** Returns Z coordinate of this disk. */
+  public double getZ() {
+    return _z;
+  }
+  
+  /** Returns inner radius of this disk. */
+  public double getMinRadius() {
+    return Math.sqrt(_rMin2);
+  }
+  
+  /** Returns outer radius of this disk. */
+  public double getMaxRadius() {
+    return Math.sqrt(_rMax2);
+  }
+  
+// -- Implementing Surface :  --------------------------------------------------
+  
+  /**
+   * Returns intersection of the specified trajectory with this surface.
+   */
+  public Intersection intersect(Trajectory trajectory) {
+    if (trajectory instanceof Line) {
+      return ((Line)trajectory).intersect(this);
+    } else if (trajectory instanceof Helix) {
+      return ((Helix)trajectory).intersect(this);
+    } else {
+      return super.intersect(trajectory);
+    }
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  double _z;
+  double _rMin2, _rMax2;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
ZPlane.java added at 1.1
diff -N ZPlane.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ZPlane.java	27 Jun 2008 02:46:33 -0000	1.1
@@ -0,0 +1,42 @@
+package org.lcsim.contrib.onoprien.crux.swim;
+
+/**
+ * {@link Surface} that represents a plane perpendicular to Z axis.
+ *
+ * @author D. Onoprienko
+ * @version $Id: ZPlane.java,v 1.1 2008/06/27 02:46:33 onoprien Exp $
+ */
+public class ZPlane extends AbstractSurface {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public ZPlane(double z) {
+    _z = z;
+  }
+  
+// -- Getters :  ---------------------------------------------------------------
+  
+  /** Returns Z coordinate of this plane. */
+  public double getZ() {
+    return _z;
+  }
+  
+// -- Implementing Surface :  --------------------------------------------------
+  
+  /**
+   * Returns intersection of the specified trajectory with this surface.
+   */
+  public Intersection intersect(Trajectory trajectory) {
+    if (trajectory instanceof Line) {
+      return ((Line)trajectory).intersect(this);
+    } else if (trajectory instanceof Helix) {
+      return ((Helix)trajectory).intersect(this);
+    } else {
+      return super.intersect(trajectory);
+    }
+  }
+
+// -- Private parts :  ---------------------------------------------------------
+  
+  double _z;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
AbstractTrajectory.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- AbstractTrajectory.java	22 Apr 2008 18:27:54 -0000	1.1
+++ AbstractTrajectory.java	27 Jun 2008 02:46:33 -0000	1.2
@@ -5,161 +5,64 @@
 /**
  * Abstract class that provides a skeletal implementation of the {@link Trajectory}
  * interface to minimize the effort required to implement this interface.
+ * <p>
+ * This class also declares a few additional methods (<tt>getLengthToZPlane</tt>,
+ * <tt>getLengthToZCylinder</tt>) that can be implemented by concrete trajectory
+ * classes to facilitate finding intersections with surfaces. Default implementation
+ * provided by this class throws <tt>UnsupportedOperationException</tt>.
  *
  * @author D. Onoprienko
- * @version $Id: AbstractTrajectory.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: AbstractTrajectory.java,v 1.2 2008/06/27 02:46:33 onoprien Exp $
  */
 abstract public class AbstractTrajectory implements Trajectory {
   
-// -- Constructors :  ----------------------------------------------------------
-  
-  protected AbstractTrajectory() {
-  }
-  
-  
-// -- Position at the given point :  -------------------------------------------
-  
-  /**
-   * Returns the position of the origin of the trajectory.
-   */
-  public Hep3Vector getOrigin() {
-    return getPointAtLength(0.);
-  }
-
-  /**
-   * Returns the position at given path length along the trajectory.
-   */
-  abstract public Hep3Vector getPointAtLength(double pathLength);
+// -- Implementing Trajectory :  -----------------------------------------------
 
   /**
-   * Returns point of closest approach to the given point.
-   */
-  public Hep3Vector getPointAtPOCA(Hep3Vector point) {
-    double pathLength = getLengthToPOCA(point);
-    return (Double.isNaN(pathLength)) ? null : getPointAtLength(pathLength);
-  }
-
-  /**
-   * Returns point where the trajectory first reaches the given radius.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
-   */
-  public Hep3Vector getPointAtZCylinder(double radius) {
-    double pathLength = getLengthToZCylinder(radius);
-    return (Double.isNaN(pathLength)) ? null : getPointAtLength(pathLength);
-  }
-
-  /**
-   * Returns point where the trajectory first reaches the given Z plane.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
+   * Returns the position of the origin of the trajectory.
+   * Implemented by forwarding the call to {@link #getPoint(double)} with zero argument.
+   * Concrete subclasses can override.
    */
-  public Hep3Vector getPointAtZPlane(double z) {
-    double pathLength = getLengthToZPlane(z);
-    return (Double.isNaN(pathLength)) ? null : getPointAtLength(pathLength);
+  public Hep3Vector getPoint() {
+    return getPoint(0.);
   }
-
-
-// -- Direction at the given point :  ------------------------------------------
   
   /**
    * Returns direction unit vector at the origin.
+   * Implemented by forwarding the call to {@link #getDirection(double)} with zero argument.
+   * Concrete subclasses can override.
    */
   public Hep3Vector getDirection() {
-    return getDirectionAtLength(0.);
+    return getDirection(0.);
   }
   
   /**
-   * Returns direction unit vector at given path length along the trajectory.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
-   */
-  abstract public Hep3Vector getDirectionAtLength(double pathLength);
-
-  /**
-   * Returns direction unit vector at the point of closest approach to the given point.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
+   * Returns intersection of this trajectory with the specified surface.
+   * Implemented by forwarding the call to {@link Surface#intersect(Surface)}.
+   * Concrete subclasses can override.
    */
-  public Hep3Vector getDirectionAtPOCA(Hep3Vector point) {
-    double pathLength = getLengthToPOCA(point);
-    return (Double.isNaN(pathLength)) ? null : getDirectionAtLength(pathLength);
+  public Intersection intersect(Surface surface) {
+    return surface.intersect(this);
   }
+  
+// -- Get trajectory parameters :  ---------------------------------------------
 
   /**
-   * Returns direction unit vector at the point where the trajectory first reaches the given radius.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
+   * Returns the value of a parameter that describes the shape of this trajectory.
+   * The parameter is identified by enum constant that belongs to a particular representation.
    */
-  public Hep3Vector getDirectionAtZCylinder(double radius) {
-    double pathLength = getLengthToZCylinder(radius);
-    return (Double.isNaN(pathLength)) ? null : getDirectionAtLength(pathLength);
+  public <T extends Enum<T>> double getParameter(T parameter) {
+    ParVector<T> v = getParameters(parameter.getClass());
+    return v.get(parameter);
   }
 
   /**
-   * Returns direction unit vector at the point where the trajectory first reaches the given Z plane.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
+   * Returns an element of a covariance matrix of parameters that describe the shape of this trajectory.
+   * The parameter is identified by enum constant that belongs to a particular representation.
    */
-  public Hep3Vector getDirectionAtZPlane(double z){
-    double pathLength = getLengthToZPlane(z);
-    return (Double.isNaN(pathLength)) ? null : getDirectionAtLength(pathLength);
+  public <T extends Enum<T>> double getCovElement(T parameter1, T parameter2) {
+    ParCovMatrix<T> m = getCovMatrix(parameter1.getClass());
+    return m.get(parameter1, parameter2);
   }
 
-  
-// -- Distance along the trajectory to something :  ----------------------------
-  
-  /**
-   * Returns path length along the trajectory to the point of closest approach to 
-   * the point supplied as an argument.
-   */
-  abstract public double getLengthToPOCA(Hep3Vector point);
-
-  /**
-   * Returns the path length along the trajectory to the point where it first reaches the given radius.
-   * Only positive solutions are sought. If no such solution exists, returns <tt>Double.NaN</tt>.
-   */
-  abstract public double getLengthToZCylinder(double radius);
-
-  /**
-   * Returns the path length along the trajectory to the point where it first reaches the given Z plane.
-   * Only positive solutions are sought. If no such solution exists, returns <tt>Double.NaN</tt>.
-   */
-  abstract public double getLengthToZPlane(double z);
-  
-
-// -- Modifying the trajectory :  ----------------------------------------------
-  
-  /** 
-   * Reverse the direction of the trajectory.
-   */
-  abstract public void reverse();
-  
-  /**
-   * Move the origin by the given path length along the trajectory.
-   * Returns <tt>false</tt> if the requested point does not exist on this trajectory.
-   */
-  abstract public boolean swim(double pathLength);
-  
-  /**
-   * Move the origin to the point of closest approach to the point supplied as an argument.
-   * Returns <tt>false</tt> if the requested point does not exist on this trajectory.
-   */
-  public boolean swimToPOCA(Hep3Vector point) {
-    double pathLength = getLengthToPOCA(point);
-    return (Double.isNaN(pathLength)) ? false : swim(pathLength);
-  }
-  
-  /**
-   * Move the origin to the point where the trajectory first reaches the given radius.
-   * Returns <tt>false</tt> if the requested point does not exist on this trajectory.
-   */
-  public boolean swimToZCylinder(double radius) {
-    double pathLength = getLengthToZCylinder(radius);
-    return (Double.isNaN(pathLength)) ? false : swim(pathLength);
-  }
-  
-  /**
-   * Move the origin to the point where the trajectory first reaches the given Z plane.
-   * Returns <tt>false</tt> if the requested point does not exist on this trajectory.
-   */
-  public boolean swimToZPlane(double z) {
-    double pathLength = getLengthToZPlane(z);
-    return (Double.isNaN(pathLength)) ? false : swim(pathLength);
-  }
-  
 }

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
Helix.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Helix.java	22 Apr 2008 18:27:54 -0000	1.1
+++ Helix.java	27 Jun 2008 02:46:33 -0000	1.2
@@ -1,30 +1,150 @@
 package org.lcsim.contrib.onoprien.crux.swim;
 
-import hep.physics.vec.BasicHep3Vector;
+import java.util.*;
+
+import hep.physics.matrix.SymmetricMatrix;
 import hep.physics.vec.Hep3Vector;
 
+import org.lcsim.contrib.onoprien.crux.util.ConstHep3Vector;
+
 /**
- * Class to represent a helical trajectory.
+ * Helical {@link Trajectory} with its axis parallel to Z.
  *
  * @author D. Onoprienko
- * @version $Id: Helix.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: Helix.java,v 1.2 2008/06/27 02:46:33 onoprien Exp $
  */
 public class Helix extends AbstractTrajectory {
   
+  /** 
+   * Emumeration of helix parameters in C-representation.
+   */
+  public enum CRep {
+    /** D0 (signed impact parameter in XY plane). */
+    D0,
+    /** Phi0. */
+    PHI0,
+    /**  Omega (signed curvature). */
+    OMEGA,
+    /** Z0. */
+    Z0,
+    /** Tangent of the dip angle. */
+    LAMBDA
+  }
+  
+  /** 
+   * Emumeration of helix parameters in W-representation.
+   */
+  public enum WRep {
+    /** X of the helix origin. */
+    X,
+    /** Y of the helix origin. */
+    Y,
+    /** Z of the helix origin. */
+    Z,
+    /** X component of the unit vector in the direction of the helix at its origin. */
+    DX,
+    /** Y component of the unit vector in the direction of the helix at its origin. */
+    DY,
+    /** Z component of the unit vector in the direction of the helix at its origin. */
+    DZ,
+    /** Amplitude of the transverse component of the unit vector in the direction of 
+     * the helix at its origin, devided by the helix radius. */
+    RO
+  }
+
 // -- Constructors :  ----------------------------------------------------------
   
   public Helix(Hep3Vector origin, Hep3Vector direction, double curvature) {
     
-    _x = origin.x();
-    _y = origin.y();
-    _z = origin.z();
+    if (origin instanceof ConstHep3Vector) {
+      _orig = (ConstHep3Vector) origin;
+    } else {
+      _orig = new ConstHep3Vector(origin);
+    }
     
     double mag = direction.magnitude();
-    _dx = direction.x() / mag;
-    _dy = direction.y() / mag;
-    _dz = direction.z() / mag;
+    _dir = new ConstHep3Vector(direction.x()/mag, direction.y()/mag, direction.z()/mag);
     
-    _ro = curvature * Math.hypot(_dx, _dy);
+    _ro = - curvature * Math.hypot(_dir.x(), _dir.y());
+  }
+  
+  public Helix(ParVector<CRep> parameters, Hep3Vector referencePoint) {
+    _ref = new ConstHep3Vector(referencePoint);
+    _parC = new ParVector<CRep>(parameters);
+    repCtoW();
+  }
+
+  public Helix(ParVector<WRep> parameters) {
+    _orig = new ConstHep3Vector(parameters.get(WRep.X), parameters.get(WRep.Y), parameters.get(WRep.Z));
+    _dir = new ConstHep3Vector(parameters.get(WRep.DX), parameters.get(WRep.DY), parameters.get(WRep.DZ));
+    _ro = parameters.get(WRep.RO);
+  }
+  
+  public Helix(Helix helix) {
+    _orig = helix._orig;
+    _dir = helix._dir;
+    _ro = helix._ro;
+    _ref = helix._ref;
+  }
+
+// -- Get helix parameters :  --------------------------------------------------
+  
+  /** 
+   * Returns helix parameters in the requested representation.
+   *
+   * @param representation  Enum class that defines helix parameters representation.
+   *                        Currently either {@link CRep} or {@link WRep}.
+   */
+  public <T extends Enum<T>> ParVector<T> getParameters(Class<T> representation) {
+    if (CRep.class.isAssignableFrom(representation)) {
+      if (_parC == null) repWtoC();
+      return (ParVector) _parC;
+    } else if (WRep.class.isAssignableFrom(representation)) {
+      return new ParVector<T>(representation, _orig.x(),_orig.y(),_orig.z(),_dir.x(),_dir.y(),_dir.z(),_ro); 
+    } else {
+      throw new IllegalArgumentException();
+    }
+  }
+  
+  /** 
+   * Returns covariance matrix for helix parameters in the requested representation.
+   *
+   * @param representation  Enum class that defines helix parameters representation.
+   *                        Currently either {@link CRep} or {@link WRep}.
+   */
+  public <T extends Enum<T>> ParCovMatrix<T> getCovMatrix(Class<T> representation) {
+    throw new UnsupportedOperationException("Covariance matrix operations are not yet implemented");  // FIXME
+  }
+  
+  public double getZPeriod() {
+    return Math.abs(_dir.z()*TWOPI / _ro);
+  }
+  
+  public double getLengthPeriod() {
+    return Math.abs(TWOPI / _ro);
+  }
+
+  /**
+   * Returns reference point used to calculate helix parameters in C-representation.
+   */
+  public ConstHep3Vector getReferencePoint() {
+    return (_ref == null) ? _orig : _ref ;
+  }
+  
+  /** 
+   * Sets the reference point for C-representation of the helix parameters.
+   * Once set by this method, the reference point will not be affected by calls to {@link #swim}.
+   * Calling this method with <tt>null</tt> vector resets the reference point to
+   * the origin of this trajectory, and allows subsequent calls to {@link #swim} to
+   * modify it.
+   */
+  public void setReferencePoint(Hep3Vector referencePoint) {
+    if (referencePoint == null) {
+      _ref = null;
+    } else {
+      _ref = new ConstHep3Vector(referencePoint);
+    }
+    _parC = null;
   }
   
 // -- Position at the given point :  -------------------------------------------
@@ -32,28 +152,28 @@
   /**
    * Returns the position of the origin of the trajectory.
    */
-  public Hep3Vector getOrigin() {
-    return new BasicHep3Vector(_x, _y, _z);
+  public ConstHep3Vector getPoint() {
+    return _orig;
   }
 
   /**
    * Returns the position at given path length along the trajectory.
    */
-  public Hep3Vector getPointAtLength(double pathLength) {
-    double nx = _dx/_ro;
-    double ny = _dy/_ro;
+  public ConstHep3Vector getPoint(double pathLength) {
+    double nx = _dir.x()/_ro;
+    double ny = _dir.y()/_ro;
     double x, y, z;
     if (Double.isInfinite(nx) || Double.isInfinite(ny)) {
-      x = _x + _dx * pathLength;
-      y = _y + _dy * pathLength;
+      x = _orig.x() + _dir.x() * pathLength;
+      y = _orig.y() + _dir.y() * pathLength;
     } else {
       double sin = Math.sin(_ro*pathLength);
       double cos1 = 1. - Math.cos(_ro*pathLength);
-      x = _x + nx * sin - ny * cos1;
-      y = _y + ny * sin + nx * cos1;
+      x = _orig.x() + nx * sin - ny * cos1;
+      y = _orig.y() + ny * sin + nx * cos1;
     }
-    z = _z + _dz * pathLength;
-    return new BasicHep3Vector(x,y,z);
+    z = _orig.z() + _dir.z() * pathLength;
+    return new ConstHep3Vector(x,y,z);
   }
   
 // -- Direction at the given point :  ------------------------------------------
@@ -61,46 +181,101 @@
   /**
    * Returns the direction unit vector at the origin.
    */
-  public Hep3Vector getDirection() {
-    return new BasicHep3Vector(_dx, _dy, _dz);
+  public ConstHep3Vector getDirection() {
+    return _dir;
   }
   
   /**
    * Returns the direction unit vector at given path length along the trajectory.
    */
-  public Hep3Vector getDirectionAtLength(double pathLength) {
+  public ConstHep3Vector getDirection(double pathLength) {
     double sin = Math.sin(_ro*pathLength);
     double cos = Math.cos(_ro*pathLength);
-    double dx = _dx * cos - _dy * sin;
-    double dy = _dy * cos + dx * sin;
-    return new BasicHep3Vector(dx, dy, _dz);
+    double dx = _dir.x() * cos - _dir.y() * sin;
+    double dy = _dir.y() * cos + _dir.x() * sin;
+    return new ConstHep3Vector(dx, dy, _dir.z());
   }
   
-// -- Distance along the trajectory to something :  ----------------------------
+// -- Intersections :  ---------------------------------------------------------
   
-  /**
-   * Returns path length along the trajectory to the point of closest approach to 
-   * the point supplied as an argument.
-   */
-  public double getLengthToPOCA(Hep3Vector point) {
-    throw new UnsupportedOperationException();  // FIXME
+  public Intersection intersect(Surface surface) {
+    if (surface instanceof Poca) {
+      return intersect((Poca) surface);
+    } else if (surface instanceof PocaXY) {
+      return intersect((PocaXY) surface);
+    } else if (surface instanceof ZPlane) {
+      return intersect((ZPlane) surface);
+    } else if (surface instanceof ZCylinder) {
+      return intersect((ZCylinder) surface);
+    } else {
+      return surface.intersect(this);
+    }
   }
-
-  /**
-   * Returns the path length along the trajectory to the point where it first reaches the given radius.
-   * Only positive solutions are sought. If no such solution exists, returns <tt>Double.NaN</tt>.
-   */
-  public double getLengthToZCylinder(double radius) {
-    throw new UnsupportedOperationException();  // FIXME
+  
+  public Intersection intersect(Poca poca) {
+    Hep3Vector point = poca.getPoint();
+    double s = 0;   // FIXME
+    return new IntersectionSingle(s, this, poca);
   }
-
-  /**
-   * Returns the path length along the trajectory to the point where it first reaches the given Z plane.
-   * Only positive solutions are sought. If no such solution exists, returns <tt>Double.NaN</tt>.
-   */
-  public double getLengthToZPlane(double z) {
-    double pathLength = (z - _z) / _dz ;
-    return (pathLength >= 0. && ! Double.isInfinite(pathLength)) ? pathLength : Double.NaN;
+  
+  public Intersection intersect(PocaXY poca) {
+    Hep3Vector point = poca.getPoint();
+    double s = 0;   // FIXME
+    return new IntersectionSingle(s, this, poca);
+  }
+  
+  public Intersection intersect(ZPlane zPlane) {
+    double s = getLengthToZ(zPlane._z);
+    return (Double.isInfinite(s)) ? new IntersectionNone(this, zPlane) : new IntersectionSingle(s, this, zPlane) ;
+  }
+  
+  public Intersection intersect(ZDisk zDisk) {
+    double s = getLengthToZ(zDisk._z);
+    if (Double.isInfinite(s)) return new IntersectionNone(this, zDisk);
+    Hep3Vector pos = getPoint(s);
+    double x = pos.x();
+    double y = pos.y();
+    double r2 = x*x + y*y;
+    return (r2 > zDisk._rMin2 && r2 < zDisk._rMax2) ? new IntersectionSingle(s, this, zDisk) : new IntersectionNone(this, zDisk);
+  }
+  
+  public Intersection intersectZCylinder(ZCylinder zCylinder) { // FIXME
+    
+    double ro2 = _ro*_ro;
+    double a1 = 1. - _dir.z()*_dir.z() - _ro*(_orig.x()*_dir.y() + _orig.y()*_dir.x());
+    double a2 = _orig.x()*_dir.x() - _orig.y()*_dir.y();
+    double deltaR = _orig.x()*_orig.x() + _orig.y()*_orig.y() - zCylinder._r*zCylinder._r;
+    double a12 = a1*a1 + ro2*a2*a2;
+    double d = 4.*a2*a2 - 4.*deltaR*a1 - ro2*deltaR*deltaR;
+    if (d < 0.) return new IntersectionNone(this, zCylinder);
+    d = Math.sqrt(d);
+    
+    double cos1 = 1. - (ro2* (2.*a2*a2 - deltaR*a1 + a2*d) ) / (2.*a12);
+    double cos2 = 1. - (ro2* (2.*a2*a2 - deltaR*a1 - a2*d) ) / (2.*a12);
+    
+    double sin1 = (- _ro* (2.*a1*a2 + ro2*deltaR*a2 + a1*d)) / (2.*a12);
+    double sin2 = (- _ro* (2.*a1*a2 + ro2*deltaR*a2 - a1*d)) / (2.*a12);
+    
+    double s1 = getLength(sin1, cos1);
+    double s2 = getLength(sin2, cos2);
+    
+    double[] s;
+    if (Double.isNaN(s1)) {
+      if (Double.isNaN(s2)) {
+        return new IntersectionNone(this, zCylinder);
+      } else {
+        s = new double[]{s2};
+      }
+    } else {
+      if (Double.isNaN(s2) || s1==s2) {
+        s = new double[]{s1};
+      } else {
+        s = new double[]{s1,s2};
+      }
+    }
+    s1 = getLengthToZ(zCylinder.getMinZ());
+    s2 = getLengthToZ(zCylinder.getMaxZ());
+    return new IntersectionPeriodicBound(false, s1, s2, s, getLengthPeriod(), this, zCylinder);
   }
   
 // -- Modifying the trajectory :  ----------------------------------------------
@@ -113,22 +288,57 @@
   }
   
   /**
-   * Move the origin by the given path length along the trajectory.
+   * Moves the origin by the specified path length along the trajectory.
+   * Returns <tt>null</tt> if an attemt to move the origin by the requested length would place
+   * it beyond the boundary of this trajectory.
+   * Unless the reference point that defines C-representation of helix parameters has
+   * been set explicitly in a constructor or through a call to {@link #setReferencePoint(Hep3Vector)}
+   * method, the new origin also becomes the new reference point.
    */
   public boolean swim(double pathLength) {
     throw new UnsupportedOperationException();  // FIXME
   }
   
+// -- Helper methods :  --------------------------------------------------------
   
+  double getLength(double sin, double cos) {
+    double ros = Math.acos(cos);
+    if (sin < 0.) {
+      ros = - ros;
+    }
+    return ros/_ro;
+  }
+  
+  /** Returns path length to Z plane specified by the argument. */
+  double getLengthToZ(double z) {
+    return (z - _orig.z()) / _dir.z();
+  }
+  
+  private void repWtoC() {
+    throw new UnsupportedOperationException();  // FIXME
+  }
+  
+  private void repCtoW() {
+    throw new UnsupportedOperationException();  // FIXME
+  }
+
 // -- Private parts :  ---------------------------------------------------------
   
-  /** Origin coordinate. */
-  private double _x, _y, _z;
-  /** Direction at origin. */
-  private double _dx, _dy, _dz;
-  /** Signed curviture. */
-  private double _omega;
+  // W-representation :
+  
+  ConstHep3Vector _orig;
+  ConstHep3Vector _dir;
+  double _ro;
+  SymmetricMatrix _covW;
+  
+  // C-representation :
+  
+  ConstHep3Vector _ref;    // Ref.point 
+  ParVector<CRep> _parC;   // D0, Phi0, Omega, Z0, Tan Lambda at XY POCA to ref.point
+  SymmetricMatrix _covC;
+  
+  static private final double TWOPI = 2. * Math.PI;
+
   
-  private double _ro;
   
 }

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
Line.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Line.java	22 Apr 2008 18:27:54 -0000	1.1
+++ Line.java	27 Jun 2008 02:46:33 -0000	1.2
@@ -1,45 +1,89 @@
 package org.lcsim.contrib.onoprien.crux.swim;
 
-import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
 
+import org.lcsim.contrib.onoprien.crux.util.ConstHep3Vector;
+
 /**
- * Class to represent a straight line trajectory.
+ * Straight line {@link Trajectory}.
  *
  * @author D. Onoprienko
- * @version $Id: Line.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: Line.java,v 1.2 2008/06/27 02:46:33 onoprien Exp $
  */
 public class Line extends AbstractTrajectory {
   
+  /** 
+   * Emumeration of line parameters in W-representation.
+   */
+  public enum WRep {
+    /** X of the line origin. */
+    X,
+    /** Y of the line origin. */
+    Y,
+    /** Z of the line origin. */
+    Z,
+    /** X component of the unit vector in the direction of the line at its origin. */
+    DX,
+    /** Y component of the unit vector in the direction of the line at its origin. */
+    DY,
+    /** Z component of the unit vector in the direction of the line at its origin. */
+    DZ
+  }
+  
 // -- Constructors :  ----------------------------------------------------------
   
   /**
    * Construct from origin and direction.
    * The direction vector does not have to be normalized.
-   * Objects supplied to this constructor will not be modified or owned.
    */
   public Line(Hep3Vector origin, Hep3Vector direction) {
-    
-    _x = origin.x();
-    _y = origin.y();
-    _z = origin.z();
-    
+    _orig = new ConstHep3Vector(origin);
+    double mag = direction.magnitude();
+    _dir = new ConstHep3Vector(direction.x()/mag, direction.y()/mag, direction.z()/mag);
+  }
+  
+  /**
+   * Construct from origin and direction.
+   * The direction vector does not have to be normalized.
+   */
+  public Line(ConstHep3Vector origin, Hep3Vector direction) {
+    _orig = origin;
     double mag = direction.magnitude();
-    _dx = direction.x() / mag;
-    _dy = direction.y() / mag;
-    _dz = direction.z() / mag;
+    _dir = new ConstHep3Vector(direction.x()/mag, direction.y()/mag, direction.z()/mag);
   }
   
   /**
    * Copy constructor.
    */
   public Line(Line line) {
-    _x = line._x;
-    _y = line._y;
-    _z = line._z;
-    _dx = line._dx;
-    _dy = line._dy;
-    _dz = line._dz;
+    _orig = line._orig;
+    _dir = line._dir;
+  }
+  
+// -- Get line parameters :  ---------------------------------------------------
+  
+  /** 
+   * Returns helix parameters in the requested representation.
+   *
+   * @param representation  Enum class that defines helix parameters representation.
+   *                        Currently either {@link CRep} or {@link WRep}.
+   */
+  public <T extends Enum<T>> ParVector<T> getParameters(Class<T> representation) {
+    if (WRep.class.isAssignableFrom(representation)) {
+      return new ParVector<T>(representation, _orig.x(),_orig.y(),_orig.z(),_dir.x(),_dir.y(),_dir.z()); 
+    } else {
+      throw new IllegalArgumentException();
+    }
+  }
+  
+  /** 
+   * Returns covariance matrix for helix parameters in the requested representation.
+   *
+   * @param representation  Enum class that defines helix parameters representation.
+   *                        Currently either {@link CRep} or {@link WRep}.
+   */
+  public <T extends Enum<T>> ParCovMatrix<T> getCovMatrix(Class<T> representation) {
+    throw new UnsupportedOperationException("Covariance matrix operations are not yet implemented");  // FIXME
   }
   
 // -- Position at the given point :  -------------------------------------------
@@ -47,15 +91,17 @@
   /**
    * Returns the position of the origin of the trajectory.
    */
-  public Hep3Vector getOrigin() {
-    return new BasicHep3Vector(_x, _y, _z);
+  public Hep3Vector getPoint() {
+    return _orig;
   }
 
   /**
    * Returns the position at given path length along the trajectory.
    */
-  public Hep3Vector getPointAtLength(double pathLength) {
-    return new BasicHep3Vector(_x + pathLength * _dx, _y + pathLength * _dy, _z + pathLength * _dz);
+  public Hep3Vector getPoint(double pathLength) {
+    return new ConstHep3Vector(_orig.x() + pathLength * _dir.x(), 
+                               _orig.y() + pathLength * _dir.y(),
+                               _orig.z() + pathLength * _dir.z());
   }
   
 // -- Direction at the given point :  ------------------------------------------
@@ -64,57 +110,14 @@
    * Returns the direction unit vector at the origin.
    */
   public Hep3Vector getDirection() {
-    return new BasicHep3Vector(_dx, _dy, _dz);
+    return _dir;
   }
   
   /**
    * Returns the direction unit vector at given path length along the trajectory.
    */
-  public Hep3Vector getDirectionAtLength(double pathLength) {
-    return new BasicHep3Vector(_dx, _dy, _dz);
-  }
-  
-// -- Distance along the trajectory to something :  ----------------------------
-  
-  /**
-   * Returns path length along the trajectory to the point of closest approach to 
-   * the point supplied as an argument.
-   */
-  public double getLengthToPOCA(Hep3Vector point) {
-    return (point.x()-_x)*_dx + (point.y()-_y)*_dy + (point.z()-_z)*_dz;
-  }
-
-  /**
-   * Returns the path length along the trajectory to the point where it first reaches the given radius.
-   * Only positive solutions are sought. If no such solution exists, returns <tt>Double.NaN</tt>.
-   */
-  public double getLengthToZCylinder(double radius) {
-    double b = _x * _dx + _y * _dy;
-    double d2 = _dx * _dx + _dy * _dy;
-    double discr = b*b - d2 * (_x * _x + _y * _y - radius * radius);
-    if ((discr < 0.) || Double.isNaN(discr) || Double.isInfinite(discr)) {
-      return Double.NaN;
-    } else {
-      discr = Math.sqrt(discr);
-      double r1 = (-b - discr) / d2;
-      double r2 = (-b + discr) / d2;
-      if ( (r1 >= 0.) && ! Double.isInfinite(r1) ) {
-        return r1;
-      } else if ( (r2 >= 0.) && ! Double.isInfinite(r2) ) {
-        return r2;
-      } else {
-        return Double.NaN;
-      }
-    }
-  }
-
-  /**
-   * Returns the path length along the trajectory to the point where it first reaches the given Z plane.
-   * Only positive solutions are sought. If no such solution exists, returns <tt>Double.NaN</tt>.
-   */
-  public double getLengthToZPlane(double z) {
-    double s = (z - _z) / _dz;
-    return (s >= 0. && s != Double.POSITIVE_INFINITY) ? s : Double.NaN ;
+  public Hep3Vector getDirection(double pathLength) {
+    return _dir;
   }
   
 // -- Modifying the trajectory :  ----------------------------------------------
@@ -123,24 +126,97 @@
    * Reverse the direction of the trajectory.
    */
   public void reverse() {
-    _dx = - _dx;
-    _dy = - _dy;
-    _dz = - _dz;
+    _dir = new ConstHep3Vector(- _dir.x(), - _dir.y(), - _dir.z());
   }
   
   /**
    * Move the origin by the given path length along the trajectory.
    */
   public boolean swim(double pathLength) {
-    _x = _x + pathLength * _dx;
-    _y = _y + pathLength * _dy;
-    _z = _z + pathLength * _dz;
+    _orig = new ConstHep3Vector(_orig.x() + pathLength * _dir.x(),
+                                  _orig.y() + pathLength * _dir.y(),
+                                  _orig.z() + pathLength * _dir.z());
     return true;
   }
   
+// -- Intersections :  ---------------------------------------------------------
+  
+  public Intersection intersect(Surface surface) {
+    if (surface instanceof Poca) {
+      return intersect((Poca) surface);
+    } else if (surface instanceof PocaXY) {
+      return intersect((PocaXY) surface);
+    } else if (surface instanceof ZPlane) {
+      return intersect((ZPlane) surface);
+    } else if (surface instanceof ZCylinder) {
+      return intersect((ZCylinder) surface);
+    } else {
+      return surface.intersect(this);
+    }
+  }
+  
+  public Intersection intersect(Poca poca) {
+    Hep3Vector point = poca.getPoint();
+    double s = (point.x()-_orig.x())*_dir.x() + (point.y()-_orig.y())*_dir.y() + (point.z()-_orig.z())*_dir.z();
+    return new IntersectionSingle(s, this, poca);
+  }
+  
+  public Intersection intersect(PocaXY poca) {
+    ConstHep3Vector point = poca.getPoint();
+    double s = ((point.x()-_orig.x())*_dir.x() + (point.y()-_orig.y())*_dir.y()) / (_dir.x()*_dir.x() + _dir.y()*_dir.y());
+    if (Double.isInfinite(s)) s = (point.z() - _orig.z()) / _dir.z();
+    return new IntersectionSingle(s, this, poca) ;
+  }
+  
+  public Intersection intersect(ZPlane zPlane) {
+    double s = (zPlane._z - _orig.z()) / _dir.z();
+    return (Double.isInfinite(s)) ? new IntersectionNone(this, zPlane) : new IntersectionSingle(s, this, zPlane) ;
+  }
+  
+  public Intersection intersect(ZDisk zDisk) {
+    double s = (zDisk._z - _orig.z()) / _dir.z();
+    if (Double.isInfinite(s)) return new IntersectionNone(this, zDisk);
+    Hep3Vector pos = getPoint(s);
+    double x = pos.x();
+    double y = pos.y();
+    double r2 = x*x + y*y;
+    return (r2 > zDisk._rMin2 && r2 < zDisk._rMax2) ? new IntersectionSingle(s, this, zDisk) : new IntersectionNone(this, zDisk);
+  }
+  
+  public Intersection intersectZCylinder(ZCylinder zCylinder) {
+    double d2 = _dir.x() * _dir.x() + _dir.y() * _dir.y();
+    if (d2 == 0.) return new IntersectionNone(this, zCylinder);
+    double b = _orig.x() * _dir.x() + _orig.y() * _dir.y();
+    double discr = b*b - d2 * (_orig.x() * _orig.x() + _orig.y() * _orig.y() - zCylinder._r * zCylinder._r);
+    if ((discr < 0.) || Double.isNaN(discr) || Double.isInfinite(discr)) {
+      return new IntersectionNone(this, zCylinder);
+    } else {
+      discr = Math.sqrt(discr);
+      double[] ss = new double[] { (-b - discr) / d2, (-b + discr) / d2};
+      boolean[] good = new boolean[2];
+      for (int i=0; i<2; i++) {
+        double s = ss[i];
+        if (Double.isInfinite(s)) {
+          good[i] = false;
+        } else {
+          double z = getPoint(s).z();
+          good[i] = z > zCylinder._zMin && z < zCylinder._zMax;
+        }
+      }
+      if (good[0] && good[1]) {
+        return new IntersectionMultiple(ss, this, zCylinder);
+      } else if (! (good[0] || good[1])) {
+        return new IntersectionNone(this, zCylinder);
+      } else {
+        double s = (good[0] ? ss[0] : ss[1]);
+        return new IntersectionSingle(s, this, zCylinder);
+      }
+    }
+  }
+
 // -- Private parts :  ---------------------------------------------------------
   
-  private double _x, _y, _z;
-  private double _dx, _dy, _dz;
+  private ConstHep3Vector _orig;
+  private ConstHep3Vector _dir;
   
 }

lcsim/src/org/lcsim/contrib/onoprien/crux/swim
Trajectory.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Trajectory.java	22 Apr 2008 18:27:54 -0000	1.1
+++ Trajectory.java	27 Jun 2008 02:46:33 -0000	1.2
@@ -3,47 +3,28 @@
 import hep.physics.vec.Hep3Vector;
 
 /**
- * Abstract class that represents a trajectory in space.
- * Trajectory is characterized by its path shape, origin, and direction.
+ * A trajectory in space.
+ * Trajectory is characterized by its shape, origin, and direction.
  *
  * @author D. Onoprienko
- * @version $Id: Trajectory.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: Trajectory.java,v 1.2 2008/06/27 02:46:33 onoprien Exp $
  */
 public interface Trajectory {
   
-// -- Position at the given point :  -------------------------------------------
+// -- Position and direction at the given point :  -----------------------------
   
   /**
    * Returns the position of the origin of the trajectory.
    */
-  public Hep3Vector getOrigin();
+  public Hep3Vector getPoint();
 
   /**
    * Returns the position at given path length along the trajectory.
-   */
-  public Hep3Vector getPointAtLength(double pathLength);
-
-  /**
-   * Returns point of closest approach to the given point.
-   */
-  public Hep3Vector getPointAtPOCA(Hep3Vector point);
-
-  /**
-   * Returns point where the trajectory first reaches the given radius.
    * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
    */
-  public Hep3Vector getPointAtZCylinder(double radius);
+  public Hep3Vector getPoint(double pathLength);
 
   /**
-   * Returns point where the trajectory first reaches the given Z plane.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
-   */
-  public Hep3Vector getPointAtZPlane(double z);
-
-
-// -- Direction at the given point :  ------------------------------------------
-  
-  /**
    * Returns direction unit vector at the origin.
    */
   public Hep3Vector getDirection();
@@ -52,46 +33,50 @@
    * Returns direction unit vector at given path length along the trajectory.
    * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
    */
-  public Hep3Vector getDirectionAtLength(double pathLength);
-
-  /**
-   * Returns direction unit vector at the point of closest approach to the given point.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
-   */
-  public Hep3Vector getDirectionAtPOCA(Hep3Vector point);
-
+  public Hep3Vector getDirection(double pathLength);
+  
+// -- Get trajectory parameters :  ---------------------------------------------
+  
   /**
-   * Returns direction unit vector at the point where the trajectory first reaches the given radius.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
+   * Returns a vector of parameters that define the shape of this trajectory.
+   * Throws <tt>IllegalArgumentException</tt> if the requested representation is not
+   * applicable to this concrete trajectory class.
+   *
+   * @param representation Enum that defines a particular representation of the  trajectory
+   *                       parameters. For example, {@link Helix} parameters can be
+   *                       returned in {@link Helix.CRep} and {@link Helix.WRep} representations.
    */
-  public Hep3Vector getDirectionAtZCylinder(double radius);
+  public <T extends Enum<T>> ParVector<T> getParameters(Class<T> representation);
 
   /**
-   * Returns direction unit vector at the point where the trajectory first reaches the given Z plane.
-   * Returns <tt>null</tt> if the requested point does not exist on this trajectory.
+   * Returns the value of a parameter that describes the shape of this trajectory.
+   * The parameter is identified by enum constant that belongs to a particular representation.
    */
-  public Hep3Vector getDirectionAtZPlane(double z);
-
-  
-// -- Distance along the trajectory to something :  ----------------------------
+  public <T extends Enum<T>> double getParameter(T parameter);
   
   /**
-   * Returns path length along the trajectory to the point of closest approach to 
-   * the point supplied as an argument.
+   * Returns a covariance matrix of parameters that define the shape of this trajectory.
+   * Throws <tt>IllegalArgumentException</tt> if the requested representation is not
+   * applicable to this concrete trajectory class.
+   *
+   * @param representation Enum that defines a particular representation of the  trajectory
+   *                       parameters. For example, {@link Helix} parameters can be
+   *                       returned in {@link Helix.CRep} and {@link Helix.WRep} representations.
    */
-  public double getLengthToPOCA(Hep3Vector point);
+  public <T extends Enum<T>> ParCovMatrix<T> getCovMatrix(Class<T> representation);
 
   /**
-   * Returns the path length along the trajectory to the point where it first reaches the given radius.
-   * Only positive solutions are sought. If no such solution exists, returns <tt>Double.NaN</tt>.
+   * Returns an element of a covariance matrix of parameters that describe the shape of this trajectory.
+   * The parameter is identified by enum constant that belongs to a particular representation.
    */
-  public double getLengthToZCylinder(double radius);
-
+  public <T extends Enum<T>> double getCovElement(T parameter1, T parameter2);
+  
+// -- Find intersection with a surface :  --------------------------------------
+  
   /**
-   * Returns the path length along the trajectory to the point where it first reaches the given Z plane.
-   * Only positive solutions are sought. If no such solution exists, returns <tt>Double.NaN</tt>.
+   * Returns intersection of this trajectory with the specified surface.
    */
-  public double getLengthToZPlane(double z);
+  public Intersection intersect(Surface surface);
   
 
 // -- Modifying the trajectory :  ----------------------------------------------
@@ -107,22 +92,4 @@
    */
   public boolean swim(double pathLength);
   
-  /**
-   * Move the origin to the point of closest approach to the point supplied as an argument.
-   * Returns <tt>false</tt> if the requested point does not exist on this trajectory.
-   */
-  public boolean swimToPOCA(Hep3Vector point);
-  
-  /**
-   * Move the origin to the point where the trajectory first reaches the given radius.
-   * Returns <tt>false</tt> if the requested point does not exist on this trajectory.
-   */
-  public boolean swimToZCylinder(double radius);
-  
-  /**
-   * Move the origin to the point where the trajectory first reaches the given Z plane.
-   * Returns <tt>false</tt> if the requested point does not exist on this trajectory.
-   */
-  public boolean swimToZPlane(double z);
-  
 }
CVSspam 0.2.8