Open omgitsraven opened 6 years ago
Thanks for the discussion!
@omgitsraven , I've added an alternate form of remap-shape
, so now you can do (remap-shape shape (x y z) y x z)
, instead of (remap-shape (shape x y z) y x z)
.
It's a small difference, but means that remap-shape
is now sequenceable:
(sequence
(sphere 1)
(remap-shape (x y z) (/ x 2) y z))
Does that accomplish what you're looking for?
@tir-kaval , feel free to open up a PR to do generalized-axis versions of functions.
I think that for generating -y
and -z
variants, @omgitsraven 's plan is a bit more efficient: we theoretically eliminate arithmetic identities, but with floating-point calculations, I can't be sure that axially-aligned generalized-axis calls would collapse down (i.e. we could end up with 0.99999999997*x + 1e-12*y - 1e-15*z
, rather than just x
).
FYI, I've continued this train of thought here: https://github.com/libfive/libfive/pull/123
OK, so I think I've finally realised that the proper approach for what I was trying to do is actually something like
(define (myscale shape)
(remap-shape shape (x y z) (/ x 2) y z))
)
(myscale (sphere 1))
where I'd been trying to write it as something like
(define (myscale x y z)
(/ x 2) y z
)
(remap-shape shape (x y z) (myscale x y z))
So my question now isn't urgent, since I do have a working way to deal with it, but just out of curiosity, I am still curious—exactly how does remap-shape
work? Is it another macro like sequence
? It doesn't look like anything else I've seen in scheme—where does the (x y z)
being passed as its second argument come from? And is there a way to apply the results of another function as its last three arguments (like with values-from
or something)?
Right now, there's not a way to bring in another function, but it may be useful to have a vector form of remap-shape
, e.g. (remap-shape shape (x y z) #[(/ x 2) y z])
, since then it's easy to call other functions and use their results.
When I was implementing the
twirl-n
functions, I was thinking about how there should probably be some way of generalizing the fact that basically every function involving ashape-remap
is probably going to involve amove
in and out of a center, and three variants to change which axis it operates on...My first thought was to write
twirl-x
normally, and then maketwirl-y
andtwirl-z
both call it only wrapped with a pair of(shape-remap (shape x y z) z y x)
(ory x z
) calls — this nearly worked, but it meant that the value passed tocenter
would be aligned along the wrong axis too.However, if there were something like
sequence
but that could takeshape-remap
calls (including their responses), and ideally also a variant of that that would call the opposite of each function in reverse order after reaching the end, then this would be much easier to work around; all of the other-axis variants in the library could be replaced with something likeTo be honest I'm not completely sure how right that example is -- I'm not sure I've got the order of operations right. But the principle should be clear, at least? This would also let people more easily apply arbitrary rotations to the transformation, instead of having to manually rotate the shape the other way before being transformed, and back afterward.
This isn't exactly urgent since it's just a convenience thing, but it seems like something that could greatly simplify working with (and implementing) transformations if it were possible.
shape-remap
s definitely suffer in terms of usability because they can't really be nested the way everything else can...