0

I have N points in [x,y,z] and this kind of takes a helix shape. Is it possible to find the central axis of such a helix. This is not a regular helix with the central axis as either of global X, Y and Z axis

When I plot the curve looks at a particular angle to the global Z axis.

enter image description here

My aim is to know the angle the central axis is making with the global z axis?

Spektre
  • 41,942
  • 8
  • 91
  • 312
qwerty123
  • 92
  • 9
  • fit cylindric surface with minimal distance to your points ... can you share the data or at least the plot so we can see some properties of the dataset ? like are the density of points constant, random , variable ... how many points per screw, screw/skew ratio etc ... The fitting itself can be simplified by starting estimate deduced form geometrical properties like avg point of slices,bbox , major axis estimate etc ... similar to [Algorithms: Ellipse matching](http://stackoverflow.com/a/36054594/2521214) – Spektre Apr 07 '17 at 17:14
  • @Spektre Added a trial plot – qwerty123 Apr 07 '17 at 17:36
  • added answer for your plot – Spektre Apr 07 '17 at 21:31

3 Answers3

1

If your N points are dense enough (or equi-distant), the tangential vectors (diff vectors of consecutive points) will form a cone whose direction of the center axis coincides with direction of the helix axis and whose base plane is orthogonal to this axis direction. A projection of the helix into this normal plane will give a circle with a center on the helix axis.

coproc
  • 5,408
  • 2
  • 17
  • 29
  • Sorry, you said tangent vectors will form a cone. Then how can I get its central axis? If we can get the normal plane, I think the helix itself can be projected right. – qwerty123 Apr 07 '17 at 19:35
  • I just realized: you do not need the axis direction, you can go directly for the normal plane. Just normalize the tangent vectors to length 1, move them to the origin, then fit a plane through the end points. – coproc Apr 07 '17 at 20:06
  • @coproc nice but will work only if the points are either uniformly distributed or randomly with uniform distribution (forming concentric circles). If they are not the result can distort to ellipse or even worse shapes. – Spektre Apr 08 '17 at 04:59
  • @Spektre Yes, but for the question, this was sufficient and simple. – qwerty123 Apr 09 '17 at 01:29
1

I do not use Matlab as I got aversion to it but based on your plot I would approach this problem like this:

  1. take first 1-2 screws and compute its BBOX

    the center point of this BBOX call A

  2. take last 1-2 screws and compute its BBOX

    the center point of this BBOX call B

  3. compute helix estimate

    So line AB should be very near to your helix axis. Now just find avg or max perpendicular distance to it that is your radius. Use these as initial values for fitting and search around them to minimize error.

    axis

    Perpendicular distance of any point P to AB can be computed with vector math like this:

    U = B-A
    V = P-A
    W = (U.V)/|U|
    D = V-W
    dist = |D|
    

    where (U.V) is dot product and |U| is vector length.

    distance

  4. fit cylinder/helix more precisely

    so just search around initial guess/estimate to minimize avg and or max distance of points and fitted cylinder/helix surface. For more info and examples see:

[Notes]

  1. If you do not know how to select screws then divide your set to halves and use one for A and second for B ...
  2. if the point density is constant you can compute curve length (sum the lines), count of screws(bumps in any axis) , height of helix (distance between first and last point) and from that infer radius as curve_length = ~sqrt((2*pi*r*screw)^2 + AB_distance^2)
Community
  • 1
  • 1
Spektre
  • 41,942
  • 8
  • 91
  • 312
  • This is more generic works without the assumptions of forming concentric circles. Equally accept this answer also – qwerty123 Apr 09 '17 at 01:30
0

I will assume that:

  • that the points on the helix are in the array pos with first dimension for time (or step) and second one for the 3 components of the position vector;

  • the time variable is stored in the array time.

You can calculate the tangent vectors:

Tangent=diff(pos(:,1:3))./(diff(time));

Then take the mean of this:

meanTangent=mean(Tangent);

and you have your axis.

usumdelphini
  • 203
  • 1
  • 10