curv3d / curv

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

Parametric vs rotate problem #95

Closed ivocavalcante closed 4 years ago

ivocavalcante commented 4 years ago

Describe the bug There seems to be a problem between parametric variables and rotate function. Using such variable in a shape constructor and then feeding the resulting shape to rotate function triggers an error.

Curv Program Working:

let
  a = 30;
in
  rect (a, 2*a) >> rotate (45*deg)

Non-working:

parametric
  a::slider[10,200] = 30;
in
  rect (a, 2*a) >> rotate (45*deg)

Outputs:

939|>    arg >> match [                                                                                 
 940|>    a :: is_num ->                                                                                 
 941|>        let // 2D rotation around the Z axis                                                       
 942|>            rot2(a,p) = cmul(p, cis a);                                                            
 943|>            b = if (shape.bbox[MIN,X] == -inf || shape.bbox[MIN,Y] == -inf                         
 944|>                    || shape.bbox[MAX,X] == inf || shape.bbox[MAX,Y] == inf)                       
 945|>                [[-inf,-inf], [inf,inf]]                                                           
 946|>            else                                                                                   
 947|>                let bv = map (p->rot2(a,p)) [                                                      
 948|>                        [shape.bbox[MIN,X], shape.bbox[MIN,Y]],                                    
 949|>                        [shape.bbox[MAX,X], shape.bbox[MIN,Y]],                                    
 950|>                        [shape.bbox[MAX,X], shape.bbox[MAX,Y]],                                    
 951|>                        [shape.bbox[MIN,X], shape.bbox[MAX,Y]],                                    
 952|>                    ];                                                                             
 953|>                in [min bv, max bv];                                                               
 954|>        in make_shape {                                                                            
 955|>            dist[x,y,z,t] :                                                                        
 956|>                let xy = rot2(-a,[x,y]);                                                           
 957|>                in shape.dist(xy[X],xy[Y],z,t),                                                    
 958|>            colour[x,y,z,t] :                                                                      
 959|>                let xy = rot2(-a,[x,y]);                                                           
 960|>                in shape.colour(xy[X],xy[Y],z,t),                                                  
 961|>            bbox : [                                                                               
 962|>                [ b[MIN,X], b[MIN,Y], shape.bbox[MIN,Z] ],
 963|>                [ b[MAX,X], b[MAX,Y], shape.bbox[MAX,Z] ],
 964|>            ],
 965|>            is_2d : shape.is_2d,
 966|>            is_3d : shape.is_3d,
 967|>        };
 968|>    {angle, axis: a} ->
 969|>        do
 970|>            assert(shape.is_3d);
 971|>        in let
 972|>            axis = normalize a;
 973|>            rot3(a,axis,p) =
 974|>                    p * cos(a)
 975|>                    - cross(axis, p) * sin(a)
 976|>                    + axis * dot(axis, p * (1 - cos a));
 977|>            b = if (shape.bbox[MIN,X] == -inf || shape.bbox[MIN,Y] == -inf
 978|>                    || shape.bbox[MIN,Z] == -inf
 979|>                    || shape.bbox[MAX,X] == inf || shape.bbox[MAX,Y] == inf
 980|>                    || shape.bbox[MAX,Z] == inf
 981|>                )
 982|>                    shape.bbox
 983|>                else
 984|>                    let bb = shape.bbox;
 985|>                        bv = map (p->rot3(-angle,axis,p)) [
 986|>                            [bb[MIN,X], bb[MIN,Y], bb[MIN,Z]],
 987|>                            [bb[MAX,X], bb[MIN,Y], bb[MIN,Z]],
 988|>                            [bb[MAX,X], bb[MAX,Y], bb[MIN,Z]],
 989|>                            [bb[MIN,X], bb[MAX,Y], bb[MIN,Z]],
 990|>                            [bb[MIN,X], bb[MIN,Y], bb[MAX,Z]],
 991|>                            [bb[MAX,X], bb[MIN,Y], bb[MAX,Z]],
 992|>                            [bb[MAX,X], bb[MAX,Y], bb[MAX,Z]],
 993|>                            [bb[MIN,X], bb[MAX,Y], bb[MAX,Z]],
 994|>                        ];
 995|>                    in [ min bv, max bv ];
 996|>        in make_shape {
 997|>            //TODO: dist p : shape.dist(...rot3(angle,axis,p[[X,Y,Z]]),p[T]),
 998|>            dist[x,y,z,t] :
 999|>                let q = rot3(angle, axis, [x,y,z]);
1000|>                in shape.dist(q[X],q[Y],q[Z],t),
1001|>            colour[x,y,z,t] :
1002|>                let q = rot3(angle, axis, [x,y,z]);
1003|>                in shape.colour(q[X],q[Y],q[Z],t),
1004|>            bbox : b,
1005|>            is_3d : true,
1006|>        };
1007|     ];

Expected behavior Simple rectangle on output window.

System Information (please complete the following information):

Additional context Using Snap package, master branch.

doug-moen commented 4 years ago

I have reproduced the bug and I am investigating a fix.