home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
p
/
ply15dat.zip
/
SPHCOIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-04
|
5KB
|
173 lines
/*
* coil.c - Create a coil of n turns between two points in space
*
* Alexander Enzmann
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifdef MAC
#include <console.h>
#endif
#include "def.h"
#include "lib.h"
static void
determine_coil_point(COORD4 *pos, COORD4 *norm,
double theta, double phi, double r0, double r1, double d0)
{
COORD4 v0, v1, vd;
double len;
/* Center of the coil */
SET_COORD4(v0, r0 * cos(theta), r0 * sin(theta), d0, 1.0);
/* Point on the coil */
SET_COORD4(*pos, (r0 + r1 * sin(phi)) * cos(theta),
(r0 + r1 * sin(phi)) * sin(theta),
(r1 * cos(phi)) + d0,
1.0);
/* Direction from center to point */
SUB3_COORD(vd, *pos, v0);
len = lib_normalize_coord3(&vd);
v0.x = r1*cos(phi)*cos(theta);
v1.x = -(r0 + r1*sin(phi))*sin(theta);
v0.y = r1*cos(phi)*sin(theta);
v1.y = (r0 + r1*sin(phi))*cos(theta);
v0.z = -r1*sin(phi);
v1.z = 0.0;
CROSS(*norm, v0, v1);
len = lib_normalize_coord3(norm);
len = DOT_PRODUCT(*norm, vd);
if (len < 0.0) {
norm->x *= -1.0;
norm->y *= -1.0;
norm->z *= -1.0;
}
norm->w = 0.0;
}
/* Wrap a coil around a sphere of radius sr, centered at d=t */
static void
generate_cyl_coil(COORD4 *start, COORD4 *end,
int turns, int step_per_turn,
double r0, double r1,
double t, double sr)
{
int i, j, k;
COORD4 p, p0, p1, n0;
COORD4 dir;
MATRIX trans, itrans;
double dist, u0, u1, d0, d1, len;
double deltad, deltau;
double t0, t1, tm;
double rt, q, rdif = r0 - r1, sr2 = sr * sr;
SUB3_COORD(dir, *end, *start);
dist = lib_normalize_coord3(&dir);
/* Figure out the transform to get from the parametrically defined
coil to the start-end line */
lib_create_canonical_matrix(itrans, trans, start, &dir);
/* Figure out the lower and upper limits that the sphere will
affect the coil */
t0 = dist * t - sr;
t1 = dist * t + sr;
tm = (t1 + t0) / 2.0;
/* Calculate the step sizes for making the coil */
deltad = dist / (double)(turns * step_per_turn);
deltau = 2.0 * PI / (double)step_per_turn;
/* Start generating the cylinders making up the coil */
for (i=0,d0=0.0;i<turns;i++) {
for (j=0;j<step_per_turn;j++,d0+=deltad) {
d1 = d0 + deltad;
u0 = (double)j * deltau;
u1 = u0 + deltau;
if (d0 > t0 && d0 < t1) {
q = fabs(d0 - tm);
q = sqrt(sr2 - q * q);
if (q > rdif)
rt = r0 + (q - rdif);
else
rt = r0;
}
else
rt = r0;
determine_coil_point(&p, &n0, u0, 0.0, rt, 0.0, d0);
lib_transform_coord(&p0, &p, trans);
p0.w = r1;
if (d1 > t0 && d1 < t1) {
q = fabs(d1 - tm);
q = sqrt(sr2 - q * q);
if (q > rdif)
rt = r0 + (q - rdif);
else
rt = r0;
}
else
rt = r0;
determine_coil_point(&p, &n0, u1, 0.0, rt, 0.0, d1);
lib_transform_coord(&p1, &p, trans);
p1.w = r1;
lib_output_cylcone(&p0, &p1, OUTPUT_CURVES);
lib_output_sphere(&p0, OUTPUT_CURVES);
}
}
/* Cap the end */
lib_output_sphere(&p1, OUTPUT_CURVES);
}
void
main(int argc, char *argv[])
{
COORD4 back_color, coil_color, dir;
COORD4 center_pt, end_pt, light;
COORD4 from, at, up;
MATRIX m1, m2;
/* We are using Polyray */
lib_set_raytracer(OUTPUT_POLYRAY);
/* output viewpoint */
SET_COORD(from, 0.0, 7.0,-7.0);
SET_COORD(at, 0.0, 1.0, 2.0);
SET_COORD(up, 0.0, 1.0, 0.0);
lib_output_viewpoint(&from, &at, &up, 30.0, 1.0, 1.0, 256, 256);
/* output background color - dark blue */
SET_COORD(back_color, 0.039, 0.18, 0.376);
lib_output_background_color(&back_color);
/* output light source */
SET_COORD4(light,-10.0, 10.0,-20.0, 0.7);
lib_output_light(&light);
SET_COORD4(light, 10.0, 10.0,-20.0, 0.7);
lib_output_light(&light);
/* output sphere color - blue */
SET_COORD4(center_pt, 0.0, 1.0, 2.0, 1.5);
SET_COORD(coil_color, 0.2, 0.2, 1.0);
lib_output_color(&coil_color, 0.1, 0.1, 0.0, 0.4, 3.0, 0.8, 1.3);
lib_output_sphere(¢er_pt, OUTPUT_CURVES);
/* output coil color - red */
SET_COORD(coil_color, 1.0, 0.2, 0.2);
lib_output_color(&coil_color, 0.2, 0.8, 0.0, 0.4, 5.0, 0.0, 0.0);
/* compute and output coil */
SET_COORD4(center_pt,-1.0,-1.0, 0.0, 1.0);
SET_COORD4(end_pt, 1.0, 3.0, 4.0, 1.0);
generate_cyl_coil(¢er_pt, &end_pt, 24, 72, 1.0, 0.05, 0.5, 1.5);
}