home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 3
/
CDASC03.ISO
/
maj
/
4174
/
dat
/
height
/
spiral.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-01
|
4KB
|
165 lines
/* Test file to create Targa height fields for POVRay -- Alexander Enzmann */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <string.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626
#endif
static float **height_buffer, **height_buffer2;
static int GridHeight, GridWidth;
static FILE *TargaFile;
static int TargaBits = 24;
static void
TargaOpen(char *filename, int x, int y)
{
unsigned char tgaheader[18];
if ((TargaFile = fopen(filename, "wb")) == NULL) {
printf("Failed to open Targa file: %s\n", filename);
exit(1);
}
memset(tgaheader, 0, 18);
tgaheader[2] = 2;
tgaheader[12] = (unsigned char)(x & 0xFF);
tgaheader[13] = (unsigned char)((x >> 8) & 0xFF);
tgaheader[14] = (unsigned char)(y & 0xFF);
tgaheader[15] = (unsigned char)((y >> 8) & 0xFF);
tgaheader[16] = TargaBits;
tgaheader[17] = 0x20;
fwrite(tgaheader, 18, 1, TargaFile);
}
static void
TargaWrite(unsigned char r, unsigned char g, unsigned char b)
{
if (TargaBits == 16) {
fputc(g, TargaFile);
fputc(r, TargaFile);
}
else if (TargaBits == 24) {
fputc(b, TargaFile);
fputc(g, TargaFile);
fputc(r, TargaFile);
}
else {
fprintf(stderr, "Wrong # of bits/pixel for Targa file: %d\n",
TargaBits);
exit(1);
}
}
static void
TargaClose()
{
fclose(TargaFile);
}
static void
write_height(float y)
{
unsigned char r, g, b;
if (y < -127.0) y = -127.0;
if (y > 127.0) y = 127.0;
y += 128.0;
r = (unsigned char)y;
y -= (float)r;
g = (unsigned char)(256.0 * y);
b = 0;
TargaWrite(r, g, b);
}
static void
alloc_height_buffer(int width, int height)
{
int i, j;
height_buffer = malloc(height * sizeof(float *));
if (height_buffer == NULL) {
printf("Failed to allocate height buffer\n");
exit(1);
}
for (i=0;i<height;i++) {
height_buffer[i] = malloc(width * sizeof(float));
if (height_buffer[i] == NULL) {
printf("Failed to allocate element %d of height buffer\n", i);
exit(1);
}
for (j=0;j<width;j++)
height_buffer[i][j] = 0.0;
}
}
void
dump_height_buffer(int width, int height)
{
int i, j;
for (i=0;i<height;i++)
for (j=0;j<width;j++)
write_height(height_buffer[i][j]);
}
/* Function is: r = c * exp(a * theta) */
static void
make_spiral(int width, int height, int turns, float swidth)
{
int i, j, k;
int x, y;
float fx, fy;
float theta, r;
float scale, offset;
int ang_steps = 8 * 360;
float delta_theta = 2.0 * M_PI / ((float)ang_steps);
float a = 1.0;
float c = 1.0;
int bump_width = 3;
/* Figure out how to scale to get the proper # of
turns into the height field */
/* r = c * exp(a * 2.0 * M_PI * turns); */
r = a * 2.0 * M_PI * ((float)turns);
scale = 0.15 * ((float)width) / (2.0 * r);
/* Now step through r, plopping height values down as we go */
for (i=0,theta=0.0;i<turns*ang_steps;i++,theta+=delta_theta) {
/* r = c * exp(a * theta); */
r = a * 2.0 * M_PI * theta;
fx = scale * r * cos(theta);
fy = scale * r * sin(theta);
x = (int)fx + width/2;
y = (int)fy + height/2;
for (j=-bump_width;j<=bump_width;j++)
for (k=-bump_width;k<=bump_width;k++)
if (x+j >= 0 && x+j < width &&
y+k >= 0 && y+k < height) {
offset = 2.0 * sqrt((float)j * (float)j + (float)k * (float)k);
height_buffer[x+j][y+k] =
(height_buffer[x+j][y+k] + (10.0 - offset)) / 2.0;
}
printf("\rT: %g ", theta);
}
}
void
main(argc, argv)
int argc;
char **argv;
{
int width = 256;
int height = 256;
int turns = 5;
float swidth = 5.0;
TargaOpen("spirhf.tga", height, width);
alloc_height_buffer(width, height);
make_spiral(width, height, turns, swidth);
dump_height_buffer(width, height);
TargaClose();
}