How to create a cylinder going from point A to point B
Jan 11, 2020 13:26:04 GMT
hokiecsgrad, r366y, and 1 more like this
Post by fremag on Jan 11, 2020 13:26:04 GMT
Cylinders are defined by their minimum and maximum height.
You can scale them to adjust their radius and translate them to change their position.
Then you can rotate them to change their orientation.
My problem was: how to rotate a cylinder so its bottom center is exactly at point A and the top is exactly at point B ?
I could solve it with the Rodrigue rotation formula.
Here is my code (C#) to get a rotation matrix that will rotate vector u so it has the same orientation as vector V:
// https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
public static Matrix Rotation(Tuple u, Tuple v)
{
double cosPhi = u.DotProduct(v);
var uv = u * v;
var uvMagnitude = u.Magnitude * v.Magnitude;
double sinPhi = uv.Magnitude / uvMagnitude;
var m1 = new Matrix(4,
cosPhi, 0, 0, 0,
0, cosPhi, 0, 0,
0, 0, cosPhi, 0,
0, 0, 0, 1
);
if (Math.Abs(sinPhi) < double.Epsilon)
{
return m1;
}
Tuple n = uv / sinPhi;
var m2 = new Matrix(4,
n.X * n.X, n.X * n.Y, n.X * n.Z, 0,
n.X * n.Y, n.Y * n.Y, n.Y * n.Z, 0,
n.X * n.Z, n.Z * n.Y, n.Z * n.Z, 0,
0, 0, 0, 0
);
var m3 = new Matrix(4,
0, -n.Z, n.Y, 0,
n.Z, 0, -n.X, 0,
-n.Y, n.X, 0, 0,
0, 0, 0, 0);
var m = m1 + (1 - cosPhi) * m2 + sinPhi * m3;
return m;
}
Then it's easy to create a cylinder going from point p1 to point p2:
public static Cylinder Cylinder(Tuple p1, Tuple p2, double radius)
{
var v = p2 - p1;
var m = Rotation(Helper.CreateVector(0, 1, 0), v.Normalize());
var cyl = new Cylinder(0, 1, true);
cyl.Scale(radius, v.Magnitude, radius);
cyl.Transform = m * cyl.Transform;
cyl.Translate(p1);
return cyl;
}
And then I could create the image I wanted: