
CamlSurf provides a small scripting language for defining, animating and displaying implicit surfaces and curves.
A script is a sequence of declarations and commands. Variables are immutable and may denote either scalar values or expressions. The language also supports functions and simple animation through the built-in variable time.
One or more script can be provided as argument on the command line:
./surface_x11.exe script1.surf script2.surf ...Extra commands may be entered on the terminal after the last script is read. The usage of the command is:
surfaces_x11.exe: [options] [<script1>] [<script2>] ...
--debug give debugging information on shaders (dev only)
--width specify the initial window width (default 800)
--height specify the initial window height (default 600)
--openGL use openGL 4 instead of GLES (experimental)
-help Display this list of options
--help Display this list of optionsRemark: currently, CamlSurf support the following backend (Windows and Cocoa (OS X) backend are planned):
If you have opam (OCaml's package manager) installed, opam update && opam install CamlSurf should work. Otherwise you may compile from github source at https://github.com/craff/CamlSurf
Comments begin with # and continue to the end of the line.
# This is a commentStatements are separated by semicolons.
let r = x^2 + y^2 + z^2;
surface sphere : r - 1;The following operators are available: +, -, *, /, ^. The latter correspond to integer power. Exponent must be a constant integer.
Standard mathematical functions include
sqrtsin, cos, tan, asin, acos, atanexp, logabssgn (used for the derivative of abs)positive (1 if argument is positive, 0 otherwise, mainly used for the derivative of max and min)negative (1 if argument is negative, 0 otherwise, mainly used for the derivative of max and min)We provide also some binary functions
min, maxExample:
let phi = (1 + sqrt(5)) / 2;
let t = cos(time / 10);Constant such as pi, e are not predefined. Then can be defined by
let pi = acos(-1);
let e = exp(1);The variables x, y, z represent the coordinates in space when drawing surfaces. Expression may use arbitrary variables, but surfaces and curves must only use x, y, z and time when doing animation.
Expressions may freely combine arithmetic operations, scalar parameters and use previously defined functions.
let p = x^2 + y^2 + z^2 - r^2;Definitions are introduced with
let name = expression;Example
let a = 0.2;
let sphere = x^2 + y^2 + z^2 - a;Variables are immutable, using a variable before giving its definition will not modify the value of the variable. In fact, an undefined name represents a variable (a parameter) and become a definition as soon as it is defined.
Redefining a name just hide the previous definition but does not change the value inside expression using the old definition (or parameter).
Example (not recommanded)
let sphere = x^2 + y^2 + z^2 - a; # a is a free parameter
let a = 0.2;
let sphere = sphere[a <- a]; # now a is defined as 0.2Functions can be declared using
let name(arg1,...,argn) = expression;Example
let q(x,y,z) = x^2 + y^2 - z^2 - 2;and later used as
surface hyperboloid : q(x,y,z);Arguments may themselves be expressions.
Some operations are provided and may be used used inside expressions:
simplify(p) to perform basic simplification.develop(p) to develop all polynomials within p.derive(p,var) to derive an expression relative a variable.p[var1 <- e1, ..., varn <- en] to perform substitution of parameter.A toplevel command allows to print expressions:
print e;Example:
let p = (2*x - x + y)*(x - y);
print p; # yield (2*x - x + y)*(x - y)
print simplify(p); # yield (x + y)*(x - y)
print develop(p); # yield x^2 - y^2A surface is defined by an implicit equation
surface name : expression;Example
surface sphere : x^2 + y^2 + z^2 - 1;A bounding expression may be specified.
surface sphere :
x^2+y^2+z^2-1
bound x^2+y^2+z^2-9;Only the points satisfying bound < 0 are rendered.
A curve is the intersection of two implicit surfaces, but it is drawn on a surface (that may be transparent).
Syntax:
curve name : polynomial on surface;Example
curve equator : y on sphere;Objects may be removed dynamically.
remove sphere;
remove equator on sphere;Some properties may be used to control the rendering of curves and surfaces. Each surface or curve will record the current value of these properties when it is defined. Properties currently include.
color = (r,g,b[,a]) : color for surfaces (default (0.75,0.75,0.4,1.0))back_color = (r,g,b,[,a]) : color for the backface of surfaces (default (0.75,0.4,0.4,1.0))back_color = none : use color for both faces.line_color = (r,g,b,[,a]) : color for curves (default (1.0,1.0,1.0,1.0))specular = value : intensity of specular light (default 0.25)shininess = value : dispersion of specular light (default 50)precision = value, precision_derive = value : control the root finding algorithm. Should be positive. More precisely, we use a subdivision method on each ray starting from the eye. On an interval I = [a,b], we consider the implicit function f restricted to I and h its Hermite interpolation of degree 3 : f(a) = h(a), f'(a) = h'(a), f(b) = h(b) and f'(b) = h'(b). To accept I without further subdivision (and use dichotomy to localise the roots using the root of h' within I), we must have:
\frac{|f - h|}{|f| + |h|} < precision\frac{|f' - h'| (b - a)}{|f| + |h|} < precision_deriveThese inequalities are tested in 3 points, among which are the roots of h' which belong to I. The other points are small random perturbation of \frac{1}{2}a+\frac{1}{2}b, and to replace missing roots: \frac{3}{4}a+\frac{1}{4}b and \frac{1}{4}a+\frac{3}{4}b.
mindivs = value minimum number of subdivisions performed when searching for roots (default 0).Colors are specified as (r,g,b,a) or (r,g,b) where each component belongs to [0,1].
A block may be used to modify rendering attributes locally. However, definition of expressions are always global.
Example to draw a transparent sphere not modifying the current color.
{
color = (0.8,0.2,0.2,0.5);
back_color = none;
surface s : x^2+y^2+z^2-1;
}Some global variables also control the rendering and affect all objects:
backgrounr = color set the background color (alpha channel is ignored)text_color = color give the color of the text showing GL configuration and FPS (alpha channel is ignored).far = value (only parts of the surface nearer from the camera than the provided value will be displayed)near = value (only parts of the surface further from the camera than the provided value will betranslateX value, translateY value, translateZ value translate the viewrotateX value, rotateY value, rotateZ value rotate the view around (0,0,0), always applied before the translation.The predefined variable time contains the elapsed time in seconds.
Example
let t = cos(time/10);
surface moving :
x^2+y^2+z^2-t;Execution may be paused using
sleep seconds;
wait; # wait until the space key is pressedExample
sleep 5;Any pause may be interrupted with the space key.
The following key bindings are provided:
let cone = x^2 + y^2 - z^2;
surface cone : cone;
let p0 = - z - 1;
line_color = (1.0, 0.0, 0.0);
curve p0 : p0 on cone;
sleep 5;
let a = 0.27;
let b = 0.002;
let c = 1e-4;
let p1 = p0 + a * (x+0.8);
let p2 = p0 - a * (x+0.8);
let p3 = x - 2*z - 1.5;
line_color = (0.0, 0.7, 0.0);
curve cp1 : p1 on cone;
curve cp2 : p2 on cone;
curve cp3 : p3 on cone;
sleep 5;
remove p0 on cone;
sleep 10;
let q = p1*p2 + b;
line_color = (0.0, 0.0, 1.0);
curve cq : q on cone;
sleep 5;
remove cp1 on cone;
remove cp2 on cone;
sleep 5;
let cubic = q*p3 - c;
line_color = (0.0, 0.0, 0.0);
curve cc : cubic on cone;
sleep 5;
remove cp3 on cone;
remove cq on cone;
sleep 5;
{
color = (0.2,0.2,0.9,0.35);
back_color = none;
surface cubic : cubic bound x^2 + y^2 - 6;
}# barth sextic with variable parameter
background = (1,1,1);
text_color = (0,0,0);
let phi = (1+sqrt(5)) / 2 ;
let t = min(1.1*cos((time-8)/11) + 0.1, 1) * phi ;
let a = min(1.1*cos((time-8)/13) + 0.1, 1) * (1+2*phi);
let p =
4 * (t^2*x^2-y^2)*(t^2*y^2-z^2)*(t^2*z^2-x^2)
- a*(x^2+y^2+z^2-1)^2 ;
translateZ -1;
surface barth : p bound x^2+y^2+z^2-5;This example illustrates the use of time to continuously deform a surface.