helix central axis angle - matlab

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.
My aim is to know the angle the central axis is making with the global z axis?

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.

I do not use Matlab as I got aversion to it but based on your plot I would approach this problem like this:
take first 1-2 screws and compute its BBOX
the center point of this BBOX call A
take last 1-2 screws and compute its BBOX
the center point of this BBOX call B
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.
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.
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:
How approximation search works
[Notes]
If you do not know how to select screws then divide your set to halves and use one for A and second for B ...
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)

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.

Related

How can I compute the diameter of the circle that circumscribes an irregular object?

I want a function to compute and get the diameter of the circle that circumscribes the object. Is there a built-in function in MATLAB to do this? Otherwise, what can I do?
Try this algorithm:
Compute the average x and average y for every point in the irregular object. This is done by taking the x and y component for every point and add them into the total x and total y and then divide by the number of points. This average x and average y point algorithm gives you a non-weighted center of the object.
Use that center point to compute the distance for every point in the irregular object again. Keeping the largest distance as the radius of the object.
Use the center point and the radius to compute the circumference.
I am submitting proof that the distance between the 2 points that are furthest apart in the object fails with a simple triangle. See image below. Also, the big-O notation for computing the two points that are the furthest apart is x^2. The big-O for this algorithm is 2x. The diameter of the circle in the image would be computed as 20; distance between -10,0 and 10,0. A circle of diameter 20 will not encompass the point # 0,-11. Any movement of the circle would automatically remove at least one of the two points used to compute the diameter of the circle because both points are on tangents.
Suppose M is a mask in BW, just do :
[b_x,b_y] = find(bwperim(M)== 1)
Check this function bwperim

Plotting a Line from a known point to points in a fitted curve in MATLAB

I have a set of data whose points I have plotted and fitted using a power of 2 fit in MATLAB. I'm trying to draw 3 lines to that curve as tangential lines. Each of these lines start from the co-ordinates of say, (x,y): (2,0) (4,0) (9,0).
Is it possible for MATLAB to draw lines from the curve to the first known point until the line has only one solution (tangent to the curve) with the curve?
I feel that this requires some sort of specified interval which tells MATLAB to step the co-ordinates until it finds the closest point. Does anyone know if this has been done or can be done at all?
From a point not lying on the curve, you want to draw a line that is tangent to it. In case of a convex function like y=2^x this is only possible from a point under the curve (not over it).
Since you already have the point (call it (a,b)), you need the slope of such a line. The slope is determined by the values (y-b)/(x-a) where (x,y) runs over the curve. Specifically, the "forward-looking" tangent has the slope equal to the minimum of (y-b)/(x-a) over all x>a. And the "backward-looking " tangent has the slope equal to the maximum of (y-b)/(x-a) over all x
Here is a very straightforward implementation of the above: I used find to restrict the search to either x>a or x<a and took min and max to find the slopes.
x = 0:0.01:4;
y = 2.^x;
a = 2;
b = 3;
k = min((y(find(x>a))-b)./(x(find(x>a))-a));
plot(x,y)
hold on
plot(x,k*(x-a)+b,'r')
k = max((y(find(x<a))-b)./(x(find(x<a))-a));
plot(x,k*(x-a)+b,'g')

How can I calculate the distance between two points along a complex path?

I have a set of lines that define a W shape. On each line I have then defined a set of M points that separated by a fixed width. Now I'd like to calculate the MxM matrix of distances where the value of (i,j) contains the along-the-path-distance between the points i and j.
Here is an of the along-the-path-distance between two points.
How can I calculate this distance in Matlab?
It mostly comes down to whether a simple algorithm that only works for this sort of shape is sufficient or if you'll need to also find the distance with different complex paths. If it's just this shape then it's rather trivial
Here the yHoriz is the y value of the horizontal line that connects the vertical lines and x and y I and J are the x and y values of the points i and j.
distance= abs(yI - yHoriz) + abs(xJ-xI) + abs(yJ - yHoriz)
You would need to check if the the points are on the same vertical line and just find the difference in their y values instead of the above value if they are on the same line.

Plotting 3xN matrix(N number of 3D points) on same graph using matlab

I've a 3xN matrix W where N is 50
W(1,1) is x coordinate of a point
W(2,1) is y coordinate of same point
W(3,1) is z coordinate of same point
Similarly:
W(1,2) is x coordinate of another point
W(2,2) is y coordinate of same point
W(3,2) is z coordinate of same point
....
Now I want to 3d plot all these 3d points on same figure using matlab. How can I plot all these
points on same figure?
Is it possible to plot this matrix using a single function call(in matlab)?
I know that plot3 can be used but it can be used for one graph at a time.
So plot3(v(1,1),v(1,2),v(1,3)); is just a single point. But how do I plot all N points?
Is there an easier and better method?
I guess you can use plot3(w(1,:),w(2,:),w(3,:)).

Creating a cylinder with axis centered differently

I know Matlab has a function called cylinder to create the points for a cylinder when number of points along the circumference, and the radius length. What if I don't want a unit cylinder, and also don't want it to center at the default axis (for example along z-axis)? What would be the easiest approach to create such a cylinder? Thanks in advance.
The previous answer is fine, but you can get matlab to do more of the work for you (because the results of cylinder separate x,y,z components you need to work a little to do the matrix multiplication for the rotation). To have the center of base of the cylinder at [x0 y0 z0], scaled by [xf yf xf] (use xf=yf unless you want an elliptic cylinder), use:
[x y z] = cylinder;
h=mesh(x*xf+x0,y*yf+y0,z*zf+z0)
If you also want to rotate it so it isn't aligned along the z-axis, use rotate. For example, to rotate about the x-axis by 90 degrees, so it's aligned along the y-axis, use:
rotate(h,[1 0 0],90)
Multiply the points by your favourite combination of a scaling matrix, a translation matrix, and a rotation matrix.