Good morning
I need some help calculating rotation transformations.
I have a vehicle that follows a path formed by a non-planar curve.
I want to get the transformation at each point of the curve for the vehicle so that:
Its x axis is collinear with the vector formed by the segment of the curve
Its z axis is collinear with the normal of the plane of the ribbon.

I get there for a plane curve, but not for a 3d curve.
How do you get the angles of rotation

It sounds like you need the angle between any 2 planes. I use the following code to get the acute angle between faces f1 and f2 (both Sketchup::Face objects):

# a Sketchup::ComponentInstance :
vehicle
# a Sketchup::Face. :
face
# a Sketchup::Edge (one of the edges that bounds the above face) :
edge
# Geom::Point3d on the above edge (can be e.g.: edge.start or edge.end ):
current_position

Can you post it? How did you constructed the ribbon from it?
(actually the model of the screenshot above would be better to share)

What is these "pn"s you mention? Are these the curve vertices or edges (curve segments)? I cant interpret this sentenceâ€¦
What is the â€śaxiszâ€ť? The z axis of the vehicle?

Here is the code to create the ribbon and place the car on the ribbon for each point on the curve.
There are sometimes errors if the curve undergoes too sudden variations

model = Sketchup.active_model
ents = model.entities
car = model.definitions.filter{|d|d.name == "car"}[0]
#spline is a fredo spline in a group
spline = model.selection[0]
curve= spline.entities[0].curve
group = ents.add_group
gents = group.entities
# initialisation offset point
p0b = []
p1b = []
for i in 0..curve.edges.length do
p0 = curve.edges[i].start.position
p1 = curve.edges[i].end.position
xaxis= (p0.vector_to(p1)).normalize
origin = p1
if i==0
zaxis = Z_AXIS
else
pm1 = curve.edges[i-1].start.position
vect = pm1.vector_to p0
zaxis = vect*xaxis
if zaxis.%(Z_AXIS) < 0
zaxis.reverse!
end
if (zaxis.angle_between(Z_AXIS)).abs() >= Math::PI/4
zaxis = xaxis*zaxis
end
if zaxis.%(Z_AXIS) < 0
zaxis.reverse!
end
end
yaxis = (xaxis*zaxis).reverse
if i==0
p0b = p0.offset(yaxis,1.m)
else
p0b = p1b
end
p1b = p1.offset(yaxis,1.m)
gents.add_face(p0,p1,p0b)
gents.add_face(p0b,p1,p1b)
tr = Geom::Transformation.new(xaxis, yaxis, zaxis, origin)
gents.add_instance(car,tr)
end

Would be more easy to imagine and analyse, if I get the model (contain the spline and car), if it is not a top secret projectâ€¦ â€¦ Can you share the .skp file?

Hi Dezmo
No nothing â€śTop secretâ€ť itâ€™s learning Ruby!
The idea is to find a generic version of path tracking by a component, to make animation. So whatever the curve, it has to be consistent. I donâ€™t have a precise model, I change the curve each time to see the result.

You can use the segments of the curve as xaxis and use the Vector3d #axes method to compute an arbitrary set of axes with the given vector as the z-axis direction. Then swap these vectors so that the directions are become as neededâ€¦