@Alasdair-McAndrew
I tried to find code that does this exactly, but failed. So I took some time try different combinations of atan acos asin until I got somewhat working solution. Then I added fixes for special cases that break the inital code.
based on your suggestion I tried some values (dx=0
, dy=0
, dz=0
) and found a case that did not work: (dx==0 && dy == 0)
.
I have added an exception that now fixes taht edge case.
(I am proud I made this work somehow, so if you find another edge case that does not work, let me know
)
link1: gist: https://gist.github.com/hrgdavor/c1bc1b4f3e3f92161eb4dd9074363793
link2: jscad.xyz with that gist: https://jscad.xyz/#https://gist.githubusercontent.com/hrgdavor/c1bc1b4f3e3f92161eb4dd9074363793/raw/1c41bbf3dc5d5af33614205ce8bd17e1e93b66f1/testCylinderFromTo.js
new version with fix:
function cylinderFromTo(p1,p2, radius){
const sqr = x=>x*x
let dx = p2[0] - p1[0]
let dy = p2[1] - p1[1]
let dz = p2[2] - p1[2]
let height = Math.sqrt( sqr(dx) + sqr(dy) + sqr(dz))
let obj = cylinder({radius, height})
if(dx || dy){
let dxy = Math.sqrt( sqr(dx) + sqr(dy))
let ay = Math.atan(dxy/dz) *(dx < 0 ? -1:1)
let az = Math.atan(dy/dx)
let ax = dz < 0 ? -Math.PI:0
obj = transforms.rotate([ax,ay,az], obj)
}
let mid = [p1[0]+dx/2,p1[1]+dy/2,p1[2]+dz/2]
return translate(mid, obj)
}
the code now works for all of these:
testCylinderFromTo([-20,30,50],[-40,-10,70]);
testCylinderFromTo([0,0,0],[10,10,10])
testCylinderFromTo([0,0,0],[20,-20,20])
testCylinderFromTo([0,0,0],[-30,30,30])
testCylinderFromTo([0,0,0],[-40,-40,40])
testCylinderFromTo([0,0,0],[15,15,-15])
testCylinderFromTo([0,0,0],[25,-25,-25])
testCylinderFromTo([0,0,0],[-35,35,-35])
testCylinderFromTo([100,0,0],[100,0,30])
testCylinderFromTo([100,0,0],[100,0,-30])
testCylinderFromTo([100,0,0],[100,30,0])
testCylinderFromTo([100,0,0],[100,-30,0])
testCylinderFromTo([100,0,0],[130,0,0])
testCylinderFromTo([100,0,0],[70,0,0])
screen: