mirror of
https://github.com/nophead/NopSCADlib.git
synced 2025-08-19 13:41:23 +02:00
Extension to belt.scad
Can now: - render open loops - twist the belt - use pulleys instead of radius in the points list Fixes some precision a few places Breaking change in belt_length(); now requires a type argument
This commit is contained in:
@@ -88,6 +88,7 @@ function scale(v) = let(s = is_list(v) ? v : [v, v, v]) //! Generate a 4x4 matr
|
||||
[0, 0, 0, 1]
|
||||
];
|
||||
|
||||
function vec2(v) = [v.x, v.y]; //! Return a 2 vector with the first two elements of `v`
|
||||
function vec3(v) = [v.x, v.y, v.z]; //! Return a 3 vector with the first three elements of `v`
|
||||
function vec4(v) = [v.x, v.y, v.z, 1]; //! Return a 4 vector with the first three elements of `v`
|
||||
function transform(v, m) = vec3(m * [v.x, v.y, v.z, 1]); //! Apply 4x4 transform to a 3 vector by extending it and cropping it again
|
||||
@@ -153,3 +154,11 @@ function circle_intersect(c1, r1, c2, r2) = //! Calculate one point where tw
|
||||
d = norm(v), // Distance between centres
|
||||
a = atan2(v.z, v.x) - acos((sqr(d) + sqr(r2) - sqr(r1)) / (2 * d * r2)) // Cosine rule to find angle from c2
|
||||
) c2 + r2 * [cos(a), 0, sin(a)]; // Point on second circle
|
||||
|
||||
function slice(v, range) = [ for (i = range) v[i] ]; //! slice a section of a vector v, takes elements from v with index in the range
|
||||
function map(v, func) = [ for (e = v) func(e) ]; //! make a new vector where the func function argument is applied to each element of the vector v
|
||||
function mapi(v, func) = [ for (i = [0:len(v)-1]) func(i,v[i]) ]; //! make a new vector where the func function argument is applied to each element of the vector v. The func will get the index number as first argument, and the element as second argument.
|
||||
function reduce(v, func, unity) = let ( r = function(i,val) i == len(v) ? val : r(i + 1, func(val, v[i])) ) r(0, unity); //! reduce a vector v to a single entity by applying the func function recursivly to the reduced value so far and the next element, starting with unity as the inital reduced value
|
||||
function sumv(v) = reduce(v, function(a, b) a + b, 0); //! sum a vector of values that can be added with "+"
|
||||
|
||||
function xor(a,b) = (a && !b) || (!a && b);
|
@@ -36,14 +36,43 @@ function circle_tangent(p1, p2) = //! Compute the clockwise tangent between two
|
||||
v = [cos(theta), sin(theta)]
|
||||
)[ p1 + r1 * v, p2 + r2 * v ];
|
||||
|
||||
function rounded_polygon_tangents(points) = //! Compute the straight sections needed to draw and to compute the lengths
|
||||
function rounded_polygon_arcs(points, tangents) = //! Compute the arcs at the points, for each point [angle,rotate_angle,length]
|
||||
let(
|
||||
len = len(points)
|
||||
) [ for (i = [0: len-1])
|
||||
let(
|
||||
p1 = tangents[(i - 1 + len) % len].y,
|
||||
p2 = tangents[i].x,
|
||||
p = points[i],
|
||||
v1 = p1 - p,
|
||||
v2 = p2 - p,
|
||||
r = abs(p.z),
|
||||
a = let( aa = acos((v1 * v2) / sqr(r)) ) cross(v1, v2)*sign(p.z) <= 0 ? aa : 360 - aa,
|
||||
l = PI * a * r / 180,
|
||||
v0 = [r, 0],
|
||||
v = let (
|
||||
vv = norm(v0-v2) < 0.001 ? 0 : abs(v2.y) < 0.001 ? 180 :
|
||||
let( aa = acos((v0 * v2) / sqr(r)) ) cross(v0, v2)*sign(p.z) <= 0 ? aa : 360 - aa
|
||||
) p.z > 0 ? 360 - vv : vv - a
|
||||
) [a, v, l]
|
||||
];
|
||||
|
||||
// we might want to remove the old rounded_polygon_tangents and to change rounded_polygon_length to use the v2 tangents
|
||||
function rounded_polygon_tangents_v2(points) = //! Compute the straight sections between a point and the next point, for each section [start_point, end_point, length]
|
||||
let(len = len(points))
|
||||
[ for(i = [0 : len - 1])
|
||||
let(ends = circle_tangent(points[i], points[(i + 1) % len]))
|
||||
[ends.x, ends.y, norm(ends.x - ends.y)]
|
||||
];
|
||||
|
||||
function rounded_polygon_tangents(points) = //! Compute the straight sections between a point and the next point, needed to draw and to compute the lengths
|
||||
let(len = len(points))
|
||||
[for(i = [0 : len - 1])
|
||||
let(ends = circle_tangent(points[i], points[(i + 1) % len]))
|
||||
for(end = [0, 1])
|
||||
ends[end]];
|
||||
|
||||
function sumv(v, i = 0, sum = 0) = i == len(v) ? sum : sumv(v, i + 1, sum + v[i]);
|
||||
//function sumv(v, i = 0, sum = 0) = i == len(v) ? sum : sumv(v, i + 1, sum + v[i]); // moved to maths.scad
|
||||
|
||||
// the cross product of 2D vectors is the area of the parallelogram between them. We use the sign of this to decide if the angle is bigger than 180.
|
||||
function rounded_polygon_length(points, tangents) = //! Calculate the length given the point list and the list of tangents computed by ` rounded_polygon_tangents`
|
||||
|
Reference in New Issue
Block a user