#version 3.7;

global_settings{
max_trace_level 4
assumed_gamma 2.2
}


#declare CSG_OVERLAP=0.00001;
//---------------------background------------------------
background{rgb <1,1,1>}


//----------------main screen control items-----------------------------


//relate on world coordinate
#declare GridUnit=1;
#declare GridThck=0.01;
#declare ObjLineThck=0.01;
#declare LayerThck=0.001;

//relate on image coordinate
#declare PixelPerUnit=100;
#declare CenterOfCoordinate=<400,300>;
#declare BleedSize=20;

#if(ObjLineThck*PixelPerUnit<=1)
    #declare ObjLineThck=1/PixelPerUnit;
#end





//-----------------------camera--------------------------
camera{
orthographic
location<(image_width/2-(CenterOfCoordinate.x-0.5))/PixelPerUnit,(image_height/2-(CenterOfCoordinate.y-0.5))/PixelPerUnit,1>
look_at<(image_width/2-(CenterOfCoordinate.x-0.5))/PixelPerUnit,(image_height/2-(CenterOfCoordinate.y-0.5))/PixelPerUnit,0>
right <-image_width/PixelPerUnit,0,0>
up <0,image_height/PixelPerUnit,0>
translate <0,0,0>
}

//---------------------Grid & Axes------------------------


#declare range_min=<(BleedSize+0.5-CenterOfCoordinate.x)/PixelPerUnit,(BleedSize+0.5-CenterOfCoordinate.y)/PixelPerUnit>;
#declare range_max=<(image_width-BleedSize+0.5-CenterOfCoordinate.x)/PixelPerUnit,(image_height-BleedSize+0.5-CenterOfCoordinate.y)/PixelPerUnit>;

#macro Grids(_background_color, _grid_color, _layer_number)
box{
<range_min.x,range_min.y,0>,<range_max.x,range_max.y,LayerThck>
texture{
    pigment{
        tiling 1
        color_map{
            [0 _background_color]
            [1-GridThck/GridUnit _background_color]
            [1-GridThck/GridUnit _grid_color]
            [1 _grid_color]
        }
        rotate x*90
        scale GridUnit
    }
    finish{ambient 1 diffuse 0}
}
translate<0,0,_layer_number*LayerThck>
}
#end

Grids(rgb<1,1,1>, rgb<0.6,0.55,0.2>,0)

#macro Axes(_layer_number)
union{
    box{
    <0,-GridThck/2,0>,<1,GridThck/2,LayerThck>
    texture{
        pigment{rgb<1,0,0>}
        finish{ambient 1 diffuse 0}
    }
    }
    box{
    <-GridThck/2,0,0>,<GridThck/2,1,LayerThck>
    texture{
        pigment{rgb<0,1,0>}
        finish{ambient 1 diffuse 0}
    }
    }
    translate <0,0,_layer_number*LayerThck>
}
#end

Axes(1)



//----------------------macros----------------------

#macro DrawPoint(_position, _color, _layer_number)
#local this_graphic=
cylinder{
<_position.x,_position.y,0>,<_position.x,_position.y,LayerThck>, ObjLineThck/2
texture{
    pigment{
        _color
    }
    finish{
        ambient 1
        diffuse 0
    }
}
no_shadow
translate <0,0,_layer_number*LayerThck>
}
this_graphic
#end








#macro DrawLineSegment(_point1, _point2, _color, _layer_number)
#local total_lgth=vlength(_point2-_point1);
#local direct_v=vnormalize(_point2-_point1);
#local angle_of_direct=acos(vdot(y,direct_v));
#local sgn_of_rotate=select(vcross(y,direct_v).z,-1,1);

#local this_graphic=
box{
<-ObjLineThck/2, 0, 0>
< ObjLineThck/2, total_lgth, LayerThck>
texture{
    pigment{
        _color
    }
    finish{
        ambient 1
        diffuse 0
    }
}
no_shadow
rotate<0,0,sgn_of_rotate*degrees(angle_of_direct)>
translate <_point1.x, _point1.y, 0>
translate <0,0,_layer_number*LayerThck>
}

this_graphic
#end



#macro DrawCircle(_center, _radius, _color, _layer_number)
#local this_graphic=
difference{
    cylinder{
    <_center.x,_center.y,0>,<_center.x,_center.y,LayerThck>, _radius+ObjLineThck/2
    }
    cylinder{
    <_center.x,_center.y,0-CSG_OVERLAP>,<_center.x,_center.y,LayerThck+CSG_OVERLAP>, _radius-ObjLineThck/2
    }
    texture{
        pigment{
            _color
        }
        finish{
            ambient 1
            diffuse 0
        }
    }
    no_shadow
    translate <0,0,_layer_number*LayerThck>
}
this_graphic

#end




#macro DrawEquation(_input_function, _color, _layer_number)
#local e=0.001;
#local f_equation=function(x,y){_input_function(x,y)};
#local f_normalized =
function(x,y){
f_equation(x,y)
/sqrt( pow((f_equation(x+e,y)-f_equation(x,y))/e,2)
      +pow((f_equation(x,y+e)-f_equation(x,y))/e,2)
     )
}

#local this_graphic=
difference{
    isosurface{
    function{f_normalized(x,y)-ObjLineThck/2}
    threshold 0
    contained_by{box{
                 <range_min.x,range_min.y,0>,
                 <range_max.x,range_max.y,LayerThck>
                 }}
    max_gradient 10
    accuracy LayerThck/2
    }
    isosurface{
    function{f_normalized(x,y)+ObjLineThck/2}
    threshold 0
    contained_by{box{
                 <range_min.x,range_min.y,0-CSG_OVERLAP>,
                 <range_max.x,range_max.y,LayerThck+CSG_OVERLAP>
                 }}
    max_gradient 10
    accuracy LayerThck/2
    }
    texture{
        pigment{
            _color
        }
        finish{
            ambient 1
            diffuse 0
        }
    }
    no_shadow
    translate <0,0,_layer_number*LayerThck>
}
this_graphic

#end

//------------------examples / applications-----------------------------

#declare f_01=function(x,y){
y-sin(x)
}
DrawEquation(f_01, rgb<0.6,0.55,0.2>,1)
DrawCircle(<1,1.8>, 0.3, rgb<0.6,0.55,0.2>, 1)
DrawLineSegment(<-3,0>, <1,1.2>, rgb<0.6,0.55,0.2>, 1)


//--------------------------------------------------------------------