Draw a sphere: Difference between revisions

Content added Content deleted
(Stronger D code)
(→‎{{header|C}}: noise texture)
Line 154: Line 154:
eeeeeeeeeeeeeeeeeeeee
eeeeeeeeeeeeeeeeeeeee
eeeeeeeeeeeee </lang>
eeeeeeeeeeeee </lang>

===Fun with 3D simplex noise texture===
[[file:sphere-perlin.png]]
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* see http://www.csee.umbc.edu/~olano/s2002c36/ch02.pdf */

static int B[] = {0x15, 0x38, 0x32, 0x2c, 0x0d, 0x13, 0x07, 0x2a};
inline int bitmix(int i, int j, int k)
{
inline int b(int i, int j, int k, int n) {
return B[((i>>n & 1) << 2) | ((j>>n & 1) << 1) | (k>>n & 1)];
}

return b(i, j, k, 0) + b(j, k, i, 1) + b(k, i, j, 2) +
b(i, j, k, 3) + b(j, k, i, 4) + b(k, i, j, 5) +
b(i, j, k, 6) + b(j, k, i, 7);
}

float noise(float x, float y, float z)
{
float s, u, v, w;
int i, j, k, dir[3] = {0}, a, b;

float weight(int d) {
float s = (dir[0] + dir[1] + dir[2]) / 6.0f;
float x = u - dir[0] + s, y = v - dir[1] + s, z = w - dir[2] + s;
float t = .6f - (x * x + y * y + z * z);
float p, q, r;
int m, b01, b2, b3, b4, b5;

m = bitmix(i + dir[0], j + dir[1], k + dir[2]);
dir[d]++;

if (t < 0) return 0;

b01 = m & 3;
b2 = m>>2 & 1, b3 = m>>3 & 1, b4 = m>>4 & 1, b5 = m>>5 & 1;
switch(b01) {
case 1: p = x, q = y, r = z; break;
case 2: p = y, q = z, r = x; break;
default: p = z, q = x, r = y; break;
}

if (b5 == b3) p = -p;
if (b5 == b4) q = -q;
if (b5 ^ (b4 ^ b3)) r = -r;
t *= t;
return 8 * t * t * (p + (b01 ? b2 ? r : q : q + r));
}

s = (x + y + z)/3;
i = floorf(x + s), j = floorf(y + s), k = floorf(z + s);

s = (i + j + k) / 6.0f;
u = x - i + s;
v = y - j + s;
w = z - k + s;

a = u>=w ? u>=v ? 0 : 1 : v>=w ? 1 : 2;
b = u< w ? u< v ? 0 : 1 : v< w ? 1 : 2;
return weight(a) + weight(3 - a - b) + weight(b) + weight(0);
}

float getnoise(float *vv)
{
float v[3], r = 0;
int i;
for (i = 256; i > 8; i >>= 1) {
v[0] = vv[0] * 256/i;
v[1] = vv[1] * 256/i;
v[2] = vv[2] * 256/i;
r += noise(v[0], v[1], v[2]) * i / 256;
}
r = fmod(r * 2 + 2, 1);
if (r < .4) return 0;
r *= -vv[0] + vv[1] + vv[2];
if (r < 0) r = .1; else r += .1;
if (r > 1) r = 1;
return sqrt(r);
}

int main()
{
unsigned char pix[256 * 256], *p = pix;
float fv[256 * 256], *pf = fv;
float v[3], x, y, z;
int i, j;
FILE *fp;


for (i = 0; i < 256 * 256; i++) *pf++ = 0, *p++ = 0;

for (p = pix, i = 0; i < 256; i++) {
x = (i - 128) / 125.0;
v[0] = (x + 1) / 2;
for (j = 0; j < 256; j++, p++) {
y = (j - 128) / 125.0;
v[1] = (y + 1) / 2;
z = x * x + y * y;

if (z > 1) { *p = 0; continue; }
z = sqrt(1 - z);
v[2] = -z;
*p = getnoise(v) ? 80 : 0;

v[2] = z;
z = getnoise(v);
if (z > 0) *p = z * 128 + 127;
}
}

fp = fopen("out.pgm", "w+");
fprintf(fp, "P5\n256 256\n255\n");
fwrite(pix, 1, 256 * 256, fp);
fclose(fp);
return 0;
}</lang>

=={{header|D}}==
=={{header|D}}==
{{trans|C}}
{{trans|C}}