2D=>3D

The 2D-figures from before can be easily extended to 3D as I just found out:

Instead of

dist = sqrt(q * q + z * z);

use the following:

double dz = max(0, z – T);
dist = sqrt(q * q + dz * dz);
dz = max(0, -z);
dist = max(dist, sqrt(q * q + dz * dz));

where T is the size of the figure in z-direction. In the image below  it is the height.

P3D_2016.06.23_20.37.19

N-sided-figure

The next step is an n-sided-figure.

There may be some more efficient ways to do this for chosen n, but in general the distance estimation works like this:

pn = PI*n;

n2p = n/(2*PI);

double a = atan2(y, x) + 2 * PI;//get angle for (x,y) in coordinate system
int b = (int) (a * n2p);//which face of the figure is closest to (x,y)
double g = 2.0 * pn * b + pn;//calculate the angle for n, which is the face-normal
V2D n = new V2D(cos(g), sin(g));//calculate face normal
return max(0, n.dot(p.getXY()) – h);//distance calculation between a point and a straight line.

In this last step, h is subtracted, to give the figure its size and if the result is smaller than zero,

zero is returned as we are „inside“ the figure which means there’s no distance to travel along the ray anymore.

Otherwise we’d only get the outline of the figure as in this picture:

P3D_2016.06.22_14.27.09

 

Here h is the chosen height of the figure, which is here the distance from center to either side in any normal- direction.

expl

 

Example: n=7

P3D_2016.06.22_14.05.52

Example: n=3P3D_2016.06.22_14.05.40

Distance Estimation Functions

I’ve developed three DE-functions for my raytracer which I’d like to share now:

In general the distance is calculated as follows:

dist = sqrt(q²+z²)

where sqrt is the square root, q will be explained for every one of the three functions and z is the given points z-coordinate.

 

First a rectangle, not a plane.

q = sqrt(max(0,|x|-u)² + max(0,|y|-v)²)

where max() returns the bigger one of the two values and |x| is the absolute value of x and u and v are the width and height of the rectangle.

By rotating the point p beforehand, one can rotate the Rectangle in the opposite direction, as normally done in raytracing,

because all objects are assumed to be centered around the origin.P3D_2016.06.20_17.26.47

A circle:

q =  max(0, sqrt(x*x + y*y) – radius)

P3D_2016.06.20_17.27.12

A 2D-Donut:

a = sqrt(x * x + y * y);

r1 = a – u;

r2 = a – v;
if(r1 < 0){
q= r1;
}else if(r2 < 0){
q=  0;
}else{
q= r2;
}

where u and v are the inner and outer radius.

(The renders are already rotated about 70°)P3D_2016.06.20_17.27.27