我在任意位置有两个物体,我想在一个和另一个之间画一个圆柱体。搜索数学解决方案告诉我,我需要分别使用点积和十字积作为角度和轴,但是我在生成四元数或将结果转换为const search = {
multiple: function (query, projection, callback) {
console.log('multiple was called');
client.connect(url, function (err, client ) {
if (err) throw err;
console.log('Connected to db');
const db = client.db(currentdb);
const collection = db.collection(currentcollection);
collection.find(query).project(projection)
.toArray(function (err, result) {
console.log('Result on the way');
if (err) throw err;
callback(result)
client.close()
});
});
}
};
的参数时丢失了。
这是我到目前为止所做的:
rotate
function dot (v1, v2) = [v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]];
function normalize (v) = v / norm(v);
function distance (v1, v2) = sqrt(
pow(v2[0] - v1[0], 2) +
pow(v2[1] - v1[1], 2) +
pow(v2[2] - v1[2], 2)
);
function lookAt(v1, v2) =
let(n1 = normalize(v1))
let(n2 = normalize(v2))
let(v = dot(n1, n2))
let(angle = [acos(v[0]), acos(v[1]), acos(v[2])])
let(axis = normalize(cross(n1, n2)))
[0, 0, 0]; // I don't know what to return here
module cylTo(v1, v2) {
translate(v1)
rotate(lookAt(v1, v2))
cylinder(distance(v1, v2), 2);
}
v1 = [-33, -20, 22];
v2 = [20, 20, -20];
// Draw sphere 1
translate(v1)
sphere(10);
// Draw sphere 2
translate(v2)
sphere(10);
// Draw cylinder between the two
cylTo(v1, v2);
需要什么,rotate()
指向另一个对象?
答案 0 :(得分:2)
我找到了一个简单的解决方案,它近似于两个点之间的圆柱体,但它并不精确,因为它产生了一个药丸(带有圆形末端),而不是一个平端的圆柱体。
// Draw cylinder between the two
hull() {
translate(v1)
sphere(2);
translate(v2)
sphere(2);
}
答案 1 :(得分:1)
以下是在OpenSCAD中用最小的算术和否三角函数在两点之间构造圆柱体的方法。这是对以上问题的确切答案。
我们通过直接计算转换矩阵来做到这一点:
function transpose(A) = [for (j = [0:len(A[0])-1]) [for(i = [0:len(A)-1])
module cyl_between(P, Q, r){
v = Q - P;
L = norm(v);
c = v / L;
is_c_vertical = ( 1 - abs(c * [0, 0, 1]) < 1e-6);
u = is_c_vertical ? [1, 0, 0] : cross([0, 0, 1], c);
a = u / norm(u);
b = cross(c, a);
MT = [a, b, c, P];
M = transpose(MT);
multmatrix(M) cylinder(h=L, r=r, $fn=30);
}
以下是上面的注释很好的版本,它解释了数学原理:
// Transpose of matrix A (swap rows and columns)
function transpose(A) = [for (j = [0:len(A[0])-1]) [for(i = [0:len(A)-1]) A[i][j]]];
// Cylinder of radius r from P to Q
module cyl_between(P, Q, r){
v = Q - P; // vector from P to Q
L = norm(v); // height of the cylnder = dist(P, Q)
c = v / L; // unit vector: direction from P to Q
is_c_vertical = ( 1 - abs(c * [0, 0, 1]) < 1e-6); //is c parallel to z axis?
u = is_c_vertical ? [1, 0, 0] : cross([0, 0, 1], c); // normal to c and Z axis
a = u / norm(u); // unit vector normal to c and the Z axis
b = cross(c, a); // unit vector normal to a and b
// [a, b, c] is an orthonormal basis, i.e. the rotation matrix; P is the translation
MT = [a, b, c, P]; // the transformation matrix
M = transpose(MT); // OpenSCAD wants vectors in columns, so we need to transpose
multmatrix(M)
cylinder(h=L, r=r, $fn=30);
}
用法:
cyl_between([1,2,3], [4,5,6], 1);
答案 2 :(得分:0)
这是您要查找的功能,manual page上有一个非常相似的示例,我认为棘手的部分是按Z,Y,X顺序应用旋转:
function lookAt(v1, v2) =
let(v = v2-v1)
[
0,
acos(v[2]/distance(v1,v2)),
atan2(v[1], v[0])
];
答案 3 :(得分:0)
尝试一下。它应该可以满足您的需求。
$fn=40;
function vectorLength(v1,v2) = sqrt(
(v2[0]-v1[0])*(v2[0]-v1[0])+
(v2[1]-v1[1])*(v2[1]-v1[1])+
(v2[2]-v1[2])*(v2[2]-v1[2]));
function lookAt(v1, v2) =
let(v = v2-v1)
[
0,
acos(v[2]/vectorLength(v1,v2)),
atan2(v[1], v[0])
];
module cylinderBetween(p1,p2,radius)
{
translate(p1)
rotate(lookAt(p1,p2))
cylinder(vectorLength(p1,p2),radius,radius);
}
P1=[2,-7,2];
P2=[4,0,6];
// Draw the cylinder between
cylinderBetween(P1,P2,.25);
// Draw the ends
translate(P1)
rotate(lookAt(P1,P2))
cylinder(.01,1,1);
translate(P2)
rotate(lookAt(P1,P2))
cylinder(.01,1,1);