Rotate Transform to point from Frame to Frame

Hi,

I’ve not been able to solve this. I want to achieve a simple cable drawing tool. My idea is to manually place Frames and then extrude a circle from Frame to Frame with Python script.

Example: I place 3 Frame features and then expect one Extrude from f1 → f2, and one from f2 → f3.

I am successful in placing the start of each Extrude at the Frame PositionMatrix, but I fail at rotating the Extrude to point towards the next Frame. I have tried following the Yellow/Orange inverse matrix example in documentation, and also a bunch of different things with the N A O P properties on the PositionMatrix.

This is my code that only does half the job so far:

from vcScript import *

comp = getComponent()
app = getApplication()

t_frames = comp.findFeature("frames")
frames = [frame for frame in t_frames.Children]
t_cables = comp.findFeature("cables")
  
def doCable(radius, color, frames):
  #cables_transform = 
  #comp.RootFeature.createFeature(VC_TRANSFORM, color+"_"+str(radius)+"mm_cable"
  t_cable = t_cables.createFeature(VC_TRANSFORM, color+"_"+str(radius)+"mm_cable")
  start_frame = frames[0]
  
  for i in range(len(frames) - 1): # skip last iteration
    #create features needed
    cyl_extrude = t_cable.createFeature(VC_EXTRUDE, "ext")
    cylinder = cyl_extrude.createFeature(VC_CYLINDER, "cyl")
    cylinder.Height = 1    
     
    #get this frame and the next
    this_frame = frames[i]
    next_frame = frames[i+1]
    
    #postion each extrude wisely, starting in this frame
    pm = this_frame.PositionMatrix
    diff_vec = next_frame.PositionMatrix.P - pm.P
    
    cyl_extrude.Length = diff_vec.length()
    
    
    pm = cyl_extrude.PositionMatrix
    print "angle: ", pm.N.angle(diff_vec) * (180/3.141)
    deg_A = pm.A.angle(diff_vec) * (180/3.141)
    deg_N = pm.N.angle(diff_vec) * (180/3.141)
    #deg_O = pm.O.angle(diff_vec) * (180/3.141)
    pm.rotateAbsY(deg_A)
    pm.rotateAbsZ(deg_N)
    #pm.rotateAbsX(deg_O)
    
    cyl_extrude.PositionMatrix = pm

  comp.rebuild()
  app.render()

doCable(20, "blue", frames) # creates a blue cable with radius 20 mm between the frames

I think you’ll need to compute something called “LookAt matrix”. With such Matrix algebra you will need to take into account the coordinate system handedness and column / row major format differences between platforms, as a solution for different platform may not work directly due to differences in those.

I don’t know if there are some helper functions in VC API that would make this easier. Another approach could be to compute similar LookAt rotation as a quaternion and then use the vcMatrix.SetQuaternion method. This would likely avoid the handedness and matrix ordering issues.