Category : Printer + Display Graphics
Archive   : PLYDAT.ZIP
Filename : WAKE.C

 
Output of file : WAKE.C contained in archive : PLYDAT.ZIP
/* Test file to create a Targa height field for POVRay -- Alexander Enzmann */
#include
#include
#include
#include
#include

#ifndef M_PI
#define M_PI 3.1415926535897932384626
#endif

static float **height_buffer, **height_buffer2;
static int GridHeight, GridWidth;

static FILE *TargaFile;

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] = 24;
tgaheader[17] = 0x20;
fwrite(tgaheader, 18, 1, TargaFile);
}

void
TargaWrite(unsigned char r, unsigned char g, unsigned char b)
{
fputc(b, TargaFile);
fputc(g, TargaFile);
fputc(r, TargaFile);
}

void
TargaClose()
{
fclose(TargaFile);
}

void
alloc_height_buffers()
{
int i, j;
GridHeight = 160;
GridWidth = 160;

height_buffer = malloc(GridHeight * sizeof(float *));
height_buffer2 = malloc(GridHeight * sizeof(float *));
if (height_buffer == NULL || height_buffer2 == NULL) {
printf("Failed to allocate height buffer\n");
exit(1);
}
for (i=0;i height_buffer[i] = malloc(GridWidth * sizeof(float));
height_buffer2[i] = malloc(GridWidth * sizeof(float));
if (height_buffer[i] == NULL || height_buffer2[i] == NULL) {
printf("Failed to allocate element %d of height buffer\n", i);
exit(1);
}
for (j=0;j height_buffer[i][j] = 0.0;
}
}

void
clear_temp_buffer()
{
int i, j;
for (i=0;i for (j=0;j height_buffer2[i][j] = -10000.0;
}


void
add_buffers()
{
int i, j;
for (i=0;i for (j=0;j if (height_buffer2[i][j] != -10000.0)
height_buffer[i][j] = (height_buffer[i][j]+height_buffer2[i][j])/2;
}

void
evaluate_wake(int x0, int z0)
{
float wave_phase, crest_angle;
float y;
int x, z;
float wave_count = 4.0;
int wave_steps = 100;
float phase_delta = 2.0 * M_PI / wave_steps;
float total_phase = 2.0 * M_PI * wave_count;
int crest_steps = 180;
float amplitude = 64.0;
float wave_x_scale = 3;
float wave_z_scale = 1.4;
int step_count = 0;
float maxy = -1000.0;
float miny = 1000.0;
float decay_factor = 0.8; /* Amount of decay by wavelength */

for (wave_phase=0.0;wave_phase<=total_phase;wave_phase+=phase_delta) {
clear_temp_buffer();
printf("Step %d of %d\r", step_count, (int)(wave_count * wave_steps));
step_count++;

/* Determine the amplitude of the wave at this phase angle */
y = amplitude * /* Full wave height */
cos(fmod(wave_phase, 2.0 * M_PI)) * /* Change with phase angle */
pow(decay_factor, wave_phase); /* Decay with distance */

if (y < miny) miny = y;
if (y > maxy) maxy = y;

/* Steps through the equation for wave crests, generating offsets */
for (crest_angle=-M_PI/2.0+M_PI/((float)crest_steps);
crest_angle crest_angle += M_PI / ((float)crest_steps)) {
x = x0 + wave_x_scale * (float)wave_phase *
(5 * cos(crest_angle) - cos(3 * crest_angle));
z = z0 + wave_z_scale * (float)wave_phase *
(sin(crest_angle) + sin(3 * crest_angle));

/* Add the deflection into the buffer */
if (x >= 0 && x < GridWidth && z >= -GridWidth/2 && z < GridHeight/2) {
if (height_buffer2[x][z + GridWidth/2] == -10000.0)
height_buffer2[x][z + GridWidth/2] = y;
}
}
add_buffers();
}
printf("Max: %f, Min: %f\n", maxy, miny);
}

void
evaluate_wake1(int x0, int z0)
{
int x, z;
float xx0, xx1, y, r, t0, t1, theta, wave_phase;
float k1, k2;
float wave_number = 1.0;
float amplitude = 128.0;
float ship_velocity = 50.0;
float wave_velocity = 50.0;
float miny = 10000.0;
float maxy = -10000.0;
float decay_factor = 0.8;
float dist_scale0 = 0.2;
float dist_scale1 = 0.1;

clear_temp_buffer();
for (x=1;x for (z=-GridWidth/2;z xx0 = x - x0;
xx1 = z - z0;
theta = atan(xx1 / xx0);
k1 = cos(theta);
k2 = sin(theta);
t0 = xx0 / ship_velocity;
t1 = fabs(xx1) / wave_velocity;
if (t1 <= t0) {
r = sqrt(xx0 * xx0 + xx1 * xx1);
wave_phase = (k1 * xx0 + k2 * xx1) * dist_scale0;
/* Determine the amplitude of the wave at this phase angle */
y = amplitude * /* Full wave height */
cos(wave_phase) * /* Change with phase angle */
pow(decay_factor, r * dist_scale1); /* Decay with distance */
if (y < miny) miny = y;
if (y > maxy) maxy = y;
height_buffer2[x][z + GridWidth/2] = y;
}
}
}
add_buffers();
}

void
dump_height_buffer()
{
unsigned char r, g, b;
float height;
int y, i, j;
for (i=0;i for (j=0;j height = height_buffer[i][j];
if (height < -128.0) height = -128.0;
if (height > 127.0) height = 127.0;
height += 128.0;
r = height;
height -= (float)r;
g = 0; /* (unsigned char)(256.0 * height); */
b = 0;
TargaWrite(r, g, b);
}
}
}

void
main()
{
alloc_height_buffers();
evaluate_wake(0, 0);
TargaOpen("wave.tga", GridWidth, GridHeight);
dump_height_buffer();

TargaClose();
}


  3 Responses to “Category : Printer + Display Graphics
Archive   : PLYDAT.ZIP
Filename : WAKE.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/