curv3d / curv

a language for making art using mathematics
Apache License 2.0
1.14k stars 73 forks source link

(int_)Slider comparison -> not a boolean? #110

Open TyberiusPrime opened 3 years ago

TyberiusPrime commented 3 years ago

Describe the bug I'm trying to write a 'sector' (circle cut out function). For testing I wanted to stick a slider on it to choose the angle. The function needs a couple of comparisons on the angle. This fails with ERROR: ((*0.017453292519943295)<=3.141592653589793) is not a boolean Leaving out the parametric slider, it works as expected

Curv Program

parametric
    set_angle:: int_slider[0,360] = 35;
in
let 
    angle = set_angle * deg;
    r = 3;
    color x = colour x
in 
intersection [
    circle r,
    union [
    polygon[
        [0,0], 
        [0,if (angle <= 180 * deg) r*2 else r*-2], 
        [r * sin angle,r * cos angle]
    ] >> colour red,
    if (angle >= 90*deg) (square r >> translate[r/2,r/2] >> color blue),
    if (angle >= 180*deg) (square r >> translate[r/2,-r/2] >> color blue),
    if (angle >= 270*deg) (square r >> translate[-r/2,-r/2] >> color blue),
    ],
] >> show_axes

It might just be me misunderstanding something about the language, though. Thanks!

TyberiusPrime commented 3 years ago

(I suppose it's this part of the documentation I'm running into:

"The shape expression that follows a parametric clause must be compiled into a GLSL shader program for execution on the GPU. This means that only a restricted subset of Curv may be used. Right now, there are too many limitations. The implementation is not yet complete."

doug-moen commented 3 years ago

Yes, this is a current limitation of the SubCurv compiler. It's also a bug, which according to my 2021 roadmap, is supposed to get fixed this year.

There is a partial workaround. To explain, I'll first note that the SubCurv compiler considers a parameter like set_angle (defined using parametric) to be a reactive variable. The local variable angle depends on set_angle, so it is a reactive expression. A condition like angle <= 180*deg is also a reactive expression.

There are limitations in SubCurv relating to if phrases containing a reactive condition.

One case is if (reactive) number else number when this phrase occurs as a list element inside of [...]. The workaround is to wrap id(...) around the if expression. Or assign the value of the if to a variable, then reference the variable inside the [...]. The second argument to polygon in your program can be fixed like this.

Another case is if (reactive) shape, and I don't have a workaround for this.

Here's a version of your program that is modified so that it compiles and runs.

parametric
    set_angle:: int_slider[0,360] = 35;
in
let 
    angle = set_angle * deg;
    r = 3;
    color x = colour x
in 
intersection [
    circle r,
    union [
    polygon[
        [0,0], 
        [0,id(if (angle <= 180 * deg) r*2 else r*-2)], 
        [r * sin angle,r * cos angle]
    ] >> colour red,
    /*
    if (angle >= 90*deg) (square r >> translate[r/2,r/2] >> color blue),
    if (angle >= 180*deg) (square r >> translate[r/2,-r/2] >> color blue),
    if (angle >= 270*deg) (square r >> translate[-r/2,-r/2] >> color blue),
    */
    ],
] >> show_axes
doug-moen commented 2 years ago

With a recent bug fix, there is no longer an error on line 14. The expression if (reactive) number else number now compiles correctly, and the workaround using id is no longer required.

However, the 3 following if statements still produce an error.