LambdaCAD (source, paper, blog post)

This is a tiny in-browser CAD tool based on the modified sphere tracing algorithm algorithm (we call it gridhopping). Edit the code and hit the build button (or shift+enter) to generate a shape.

size:      resolution:

Instructions

The polygonization occurs in a cube centered at the origin and with side length equal to size. This cube is partitioned into pow(resolution, 3) cells. If a surface of the shape passes through a cell, polygons (triangles) are generated to approximate this. You can vary the size and resolution parameters to generate more or less detailed 3D models, depending on your requirements.

Anything you enter will be lost as soon as this page is reloaded. Thus, when building your own models, it is advised to store them in a text file locally on your computer and use copy-paste them into the code area above when you need to visualize and/or export to STL.

Examples

As explained, the gridhopping algorithm is used to polygonize implicit functions (or signed distance bounds) of the form F(x, y, z)=0. Note, however, that F has to be Lipschitz continuous in order to obtain correct results. Read more about this contraint here.

In LambdaCAD, this function is set by the user by writing a small piece of JavaScript code. For example, the following code defines a sphere with a radius equal to 0.4 centered at the origin:

// sqrt(x^2 + y^2 + z^2) - radius = 0
return function (x, y, z) {
	const radius = 0.4;
	return Math.sqrt(x*x + y*y + z*z) - radius;
}

You can achieve the same with a built-in function:

return sphere(0.4);

A more complicated example:

return function (x, y, z) {
	const scale = 6;

	x *= scale;
	y *= scale;
	z *= scale;

	const r = Math.sqrt(x*x + y*y + z*z);
	const phi = Math.atan2(y, x);
	const r1 = Math.sin(1.5 * phi) + 1.5;
	const z1 = Math.cos(1.5 * phi);
	const r2 = Math.sin(1.5 * phi + 3.14156) + 1.5;
	const z2 = Math.cos(1.5 * phi + 3.14156);

	const x1=r1*Math.cos(phi), y1=r1*Math.sin(phi);
	const x2=r2*Math.cos(phi), y2=r2*Math.sin(phi);

	return (Math.min(
		Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1)+(z-z1)*(z-z1)),
		Math.sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2)+(z-z2)*(z-z2))) - 0.3)/3.0/scale;
};

More examples can be found here.

About

Copyright (c) 2020, Nenad Markuš. All rights reserved.

Read more about the project at https://github.com/nenadmarkus/gridhopping.

You can reach me at nenad.markus@protonmail.com.