Re: 3D error ellipse
Joaquim Luis <[email protected]>
| Newsgroups | gmane.comp.gis.gmt.user |
|---|---|
| Message-ID | <[email protected]> |
OK, here goes. It's a stand-alone code with a GMT style on line help. You will be interested in -E and -M options > Hi Joaquim, > > really very kind from you. If you want to send it to me, I'll be glad > to try with it. > > Thank you. > > Federica Ferrarini > > > ***************************************************************** > > Federica Ferrarini PhD > Laboratorio di Geodinamica e Sismogenesi - Dip.to di Scienze P.U.Ter. > Campus Universitario - 66013 Chieti Scalo, CHIETI, Italy. > Tel +39-(0)871-3556453 > Fax +39-(0)871-3556454 > > To unsubscribe, send the message "signoff gmt-help" to > [email protected] > > To unsubscribe, send the message "signoff gmt-help" to [email protected]
solidos.c
(text/plain, 22.7 KB)
/*
*
* constroi corpos solidos
*
* Author: J. Luis
* Date: 28 Outubro, 2000
* 09-12-00 acrecentei um corpo gaussiano
* Revision 03-02-01 Bug na opcao piramide
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define CHUNK 2000
#define FALSE 0
#define TRUE 1
#define M_PI 3.14159265358979323846
#define D2R (M_PI / 180.0)
#define DPI (2 * M_PI)
#define PI2 (M_PI /2.)
#define R2D (180.0 / M_PI)
//#define ln(x) (((x) <= 0.0) ? 0.0 : (double) log((double)x))
struct CIRC {
double x;
double y;
} *circ;
struct TRIANG {
double x[3];
double y[3];
double z[3];
} *tri;
int cilindro (double rad_c, double height_c, double z_c, double x0, double y0, int n_pts);
int paralelo (double a, double b, double c, double z_c, double x0, double y0);
int five_psoid (double a, double b, double c, double z_c, int n_pts, int n_slice, double x0, double y0, int cone, int piram, int sino, int hemi);
void euler (double phi, double teta, double psi, int n_pts, double x0, double y0, double z_c);
double gaussian (double rad, double half_width);
double area (int n_pts);
float n_sig = 2; /* Number of sigmas which will determine the bell's base width */
main(int argc, char **argv) {
int error = FALSE, cilinder = FALSE, rotate = FALSE, multi = FALSE;
int cone = FALSE, piram = FALSE, ellipsoid = FALSE, sphere = FALSE;
int hemi = FALSE, verbose = FALSE, paralelogram = FALSE;
int sino = FALSE;
int i, j, j1, n_body = 0;
int n_pts = 24; /* divide a circle in 15 degrees intervals */
int n_slice = 5; /* some bodies are constructed as pile of n_slice */
double x0 = 0., y0 = 0., rad_c, z_c, height_c, azim, inc, dec;
double a, b, c, h_bell, sigma_x, sigma_y;
char format[512];
azim = inc = dec = 0.;
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
/* Common parameters */
case '\0':
error = TRUE;
break;
case 'B':
j = sscanf(&argv[i][2], "%lf/%lf/%lf/%lf/%f/%d/%d", &h_bell, &sigma_x, &sigma_y, &z_c, &n_sig, &n_pts, &n_slice);
if (j < 4) {
fprintf (stderr, "%s: SYNTAX ERROR -G option: Wrong number of arguments %d\n", argv[0], j);
error = TRUE;
}
sino = TRUE;
n_body++;
break;
case 'C':
j = sscanf(&argv[i][2], "%lf/%lf/%lf/%d", &rad_c, &height_c, &z_c, &n_pts);
if (j < 3) {
fprintf (stderr, "%s: SYNTAX ERROR -C option: Wrong number of arguments %d\n", argv[0], j);
error = TRUE;
}
cilinder = TRUE;
n_body++;
break;
case 'c':
j = sscanf(&argv[i][2], "%lf/%lf/%lf/%lf/%d", &a, &b, &c, &z_c, &n_pts);
if (j < 3) {
fprintf (stderr, "%s: SYNTAX ERROR -c option: Wrong number of arguments %d\n", argv[0], j);
error = TRUE;
}
cone = TRUE;
n_body++;
break;
case 'R':
sscanf(&argv[i][2], "%lf/%lf/%lf", &azim, &inc, &dec);
rotate = TRUE;
break;
case 'E':
j = sscanf(&argv[i][2], "%lf/%lf/%lf/%lf/%d/%d", &a, &b, &c, &z_c, &n_pts, &n_slice);
if (j < 4) {
fprintf (stderr, "%s: SYNTAX ERROR -E option: Wrong number of arguments %d\n", argv[0], j);
error = TRUE;
}
ellipsoid = TRUE;
n_body++;
break;
case 'H':
hemi = TRUE;
break;
case 'M':
multi = TRUE;
break;
case 'P':
j = sscanf(&argv[i][2], "%lf/%lf/%lf/%lf", &a, &b, &c, &z_c);
if (j != 4) {
fprintf (stderr, "%s: SYNTAX ERROR -P option: Wrong number of arguments %d\n", argv[0], j);
error = TRUE;
}
paralelogram = TRUE;
n_body++;
break;
case 'p':
j = sscanf(&argv[i][2], "%lf/%lf/%lf/%lf", &a, &b, &c, &z_c);
if (j != 4) {
fprintf (stderr, "%s: SYNTAX ERROR -p option: Wrong number of arguments %d\n", argv[0], j);
error = TRUE;
}
a /= 2.0; b /= 2.0;
n_pts = 4;
piram = TRUE;
n_body++;
break;
case 'S':
j = sscanf(&argv[i][2], "%lf/%lf/%d/%d", &a, &z_c, &n_pts, &n_slice);
if (j < 2) {
fprintf (stderr, "%s: SYNTAX ERROR -S option: Wrong number of arguments %d\n", argv[0], j);
error = TRUE;
}
sphere = TRUE;
n_body++;
break;
case 'V':
verbose = TRUE;
break;
case 'X':
sscanf(&argv[i][2], "%lf", &x0);
break;
case 'Y':
sscanf(&argv[i][2], "%lf", &y0);
break;
default:
error = TRUE;
break;
}
}
}
if (argc == 1) { /* Display usage */
fprintf(stderr, "solidos - calculates a solid surface as a union of triangular facets.\n\n");
fprintf(stderr,"usage: solidos [-E<semi_x/semi_y/semi_z/z_center[/npts/n_slice]>]\n");
fprintf(stderr," [-S<rad/z_center[/npts/n_slice]>] [-B<height/sx/sy/z0[/n_sig/npts/n_slice]>]\n");
fprintf(stderr," [-C<rad/height/z0[/npts]>] [-c<semi_x/semi_y/height/z0[/npts]>]\n");
fprintf(stderr," [-P<side_x/side_y/side_z/z0>] [-R<azim/inc/dec>]\n");
fprintf(stderr," [-p<side_x/side_y/height/z0>] [-M] [-H] [-X<x0>] [-Y<y0>]\n\n");
fprintf(stderr, "\tBODIES:\n");
fprintf(stderr,"\t-B bell (gaussian) of height <height> with caracteristic standard\n");
fprintf(stderr,"\t deviation <sx> and <sy>. The base width (located at depth <z0>) is\n");
fprintf(stderr,"\t controled by the number of sigma-limits (<n_sig>) [Default = 2.0]\n");
fprintf(stderr,"\t-C cilinder of radius <rad> height <height> and base at depth <z0>\n");
fprintf(stderr,"\t-c cone of semi axes <semi_x/semi_y> (that means it can be elliptic)\n");
fprintf(stderr,"\t height <height> and base at depth <z0>\n");
fprintf(stderr,"\t-E ellipsoid of semi axes <semi_x/semi_y/semi_z> and center\n");
fprintf(stderr,"\t depth <z_center>\n");
fprintf(stderr,"\t-P paralelogram of sides <x/y/z> and base at depth <z0>\n");
fprintf(stderr,"\t-p piramid of sides <x/y> height <height> and base at depth <z0>\n");
fprintf(stderr,"\t-S sphere of radius <rad> and center at depth <z_center>\n");
fprintf(stderr,"\n\tCOMMON MEANING PARAMETERS:\n");
fprintf(stderr,"\t npts -> number of points in which the circle is descretized\n");
fprintf(stderr,"\t [Default = 24].\n");
fprintf(stderr,"\t n_slice -> some bodies are constructed by a pile of slices.\n");
fprintf(stderr,"\t Spheres and Ellipsoides are made by 2*n_slice.\n");
fprintf(stderr,"\t Bells are made by n_slice. [Default = 5]\n");
fprintf(stderr,"\t z_center -> body's center of mass depth (applies to sphere\n");
fprintf(stderr,"\t and ellipsoide) [positive up].\n");
fprintf(stderr,"\t z0 -> depth of body's base (applies to remanent bodies)\n");
fprintf(stderr,"\n\tOPTIONS:\n");
fprintf(stderr,"\t-M output triangles as multiple segments separated by > flag\n");
fprintf(stderr,"\t-R rotate body by azimuth inclination and declination\n");
fprintf(stderr,"\t (follows the convention of Euler angles)\n");
fprintf(stderr,"\t-X -Y to shift origin of the body by <x0> and/or <y0>\n");
exit (-1);
}
if (error) exit (-1);
if (!n_body) {
fprintf (stderr, "%s: Error. Must select one of -C -E -G -S -c -P options\n", "solidos");
exit (-1);
}
else if (n_body > 1) {
fprintf (stderr, "%s: Error. Choose only one of -C -E -G -S -c -P options\n", "solidos");
exit (-1);
}
if (cilinder)
n_pts = cilindro (rad_c, height_c, z_c, x0, y0, n_pts);
else if (ellipsoid)
n_pts = five_psoid (a, b, c, z_c, n_pts, n_slice, x0, y0, FALSE, FALSE, FALSE, hemi);
else if (sphere)
n_pts = five_psoid (a, a, a, z_c, n_pts, n_slice, x0, y0, FALSE, FALSE, FALSE, hemi);
else if (cone)
n_pts = five_psoid (a, b, c, z_c, n_pts, 1, x0, y0, cone, FALSE, FALSE, hemi);
else if (piram)
n_pts = five_psoid (a, b, c, z_c, n_pts, 1, x0, y0, FALSE, piram, FALSE, hemi);
else if (sino)
n_pts = five_psoid (sigma_x, sigma_y, h_bell, z_c, n_pts, n_slice, x0, y0, FALSE, FALSE, sino, hemi);
else if (paralelogram)
n_pts = paralelo (a, b, c, z_c, x0, y0);
if (rotate)
euler (azim, inc, dec, n_pts, x0, y0, z_c);
if (!multi)
sprintf (format,"%s\n\0", "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f");
else
sprintf (format,"%s\n\0", ">\n%.3f %.3f %.3f\n%.3f %.3f %.3f\n%.3f %.3f %.3f");
for (i = 0; i < n_pts; i++) {
fprintf (stdout, format, tri[i].x[0], tri[i].y[0], tri[i].z[0], tri[i].x[1], tri[i].y[1], tri[i].z[1], tri[i].x[2], tri[i].y[2], tri[i].z[2]);
}
if (verbose) {
fprintf (stderr, "%d triangles\n",n_pts);
fprintf (stderr, "body area = %g\n", area (n_pts));
}
free ((void *)tri);
}
int five_psoid (double a, double b, double c, double z_c, int n_pts, int n_slice, double x0, double y0, int cone, int piram, int sino, int hemi) {
/* Constructs either a sphere, ellipsoid, cone, piramid, or a bell
/* as a union of triagular facets. Returns number of triangles. */
double z_top, z_bot, dfi, d_sli, ai0, ai1, bi0, bi1, ci, zi0, zi1;
double d_tet, half_width_x, half_width_y, dx, dy, dz, rad_x, rad_y;
int i, j, j1, k, l, m, m1, m2, n = 0, n_tri, first = TRUE;
struct CIRC *ellipse[2];
n_tri = (hemi) ? 2 * n_pts * n_slice: 2 * (n_pts * (n_slice*2 - 1));
ellipse[0] = (struct CIRC *) calloc ((size_t) (n_pts+1), sizeof(struct CIRC));
ellipse[1] = (struct CIRC *) calloc ((size_t) (n_pts+1), sizeof(struct CIRC));
if ((tri = (struct TRIANG *) calloc ((size_t) (n_tri), sizeof(struct TRIANG)) ) == NULL) {
fprintf (stderr, "Fatal Error: %s (five_psoid) could not allocate memory, n = %d\n", "solidos", n_tri);
exit (-1);
}
dfi = (DPI/n_pts); d_tet = (PI2/n_slice);
d_sli = c / n_slice;
z_top = z_c + c; z_bot = z_c;
half_width_x = 0.5 * a; half_width_y = 0.5 * b;
dx = n_sig * a / n_slice; dy = n_sig * b / n_slice;
dz = c / n_slice; /* repeated but ok */
for (j = 0; j < n_slice; j++) {
j1 = j + 1;
if (cone || piram) {
ai0 = j * a / n_slice; bi0 = j * b / n_slice;
zi0 = z_top - j * d_sli;
ai1 = j1 * a / n_slice; bi1 = j1 * b / n_slice;
zi1 = z_top - j1 * d_sli;
}
else if (sino) { /* Bell shaped volume */
rad_x = j * dx; rad_y = j * dy;
ai0 = rad_x; bi0 = rad_y;
zi0 = z_bot + c * gaussian (rad_x, half_width_x);
rad_x = j1 * dx; rad_y = j1 * dy;
ai1 = rad_x; bi1 = rad_y;
zi1 = z_bot + c * gaussian (rad_x, half_width_x);
/* A fatia constante. Preciso de descobrir como controlar o tamanho da base
rad_x = a*sqrt(2*log(c/(c-j*dz)));
rad_y = b*sqrt(2*log(c/(c-j*dz)));
ai0 = rad_x; bi0 = rad_y;
zi0 = z_bot + c - j*dz;
rad_x = a*sqrt(2*log(c/(c-j1*dz)));
rad_y = b*sqrt(2*log(c/(c-j1*dz)));
ai1 = rad_x; bi1 = rad_y;
zi1 = z_bot + c - j1*dz;
if (j1 == n_slice) {ai1 = ai0; bi1 = bi0;} */
}
else { /* Ellipsoide or Sphere */
ai0 = a*cos(PI2-j*d_tet); bi0 = b*cos(PI2-j*d_tet);
zi0 = z_top - c * (1. - sqrt(1. - (ai0/a)*(ai0/a)));
ai1 = a*cos(PI2-j1*d_tet); bi1 = b*cos(PI2-j1*d_tet);
zi1 = z_top - c * (1. - sqrt(1. - (ai1/a)*(ai1/a)));
}
for (i = 0; i < n_pts; i++) { /* compute slice j */
ellipse[0][i].x = x0 + ai0 * cos (i*dfi);
ellipse[0][i].y = y0 + bi0 * sin (i*dfi);
ellipse[1][i].x = x0 + ai1 * cos (i*dfi);
ellipse[1][i].y = y0 + bi1 * sin (i*dfi);
}
ellipse[0][n_pts].x = ellipse[0][0].x; /* close slice "contour" */
ellipse[0][n_pts].y = ellipse[0][0].y;
ellipse[1][n_pts].x = ellipse[1][0].x;
ellipse[1][n_pts].y = ellipse[1][0].y;
/* Calculates vertex of triangles in slice j */
i = 0;
if (first) {
for (m = 0; m < n_pts ; m++) {
tri[m].x[0] = ellipse[0][i].x;
tri[m].y[0] = ellipse[0][i].y;
tri[m].z[0] = zi0;
tri[m].x[1] = ellipse[1][i+1].x;
tri[m].y[1] = ellipse[1][i+1].y;
tri[m].z[1] = zi1;
tri[m].x[2] = ellipse[1][i].x;
tri[m].y[2] = ellipse[1][i].y;
tri[m].z[2] = zi1;
i++;
}
}
else {
for (m = (j-1)*n_pts; m < j*n_pts ; m++) {
/* First triangle */
m1 = 2 * m + n_pts; m2 = 2 * m + 1 + n_pts;
tri[m1].x[0] = ellipse[0][i].x;
tri[m1].y[0] = ellipse[0][i].y;
tri[m1].z[0] = zi0;
tri[m1].x[1] = ellipse[1][i+1].x;
tri[m1].y[1] = ellipse[1][i+1].y;
tri[m1].z[1] = zi1;
tri[m1].x[2] = ellipse[1][i].x;
tri[m1].y[2] = ellipse[1][i].y;
tri[m1].z[2] = zi1;
/* Second triangle */
tri[m2].x[0] = ellipse[0][i].x;
tri[m2].y[0] = ellipse[0][i].y;
tri[m2].z[0] = zi0;
tri[m2].x[1] = ellipse[0][i+1].x;
tri[m2].y[1] = ellipse[0][i+1].y;
tri[m2].z[1] = zi0;
tri[m2].x[2] = ellipse[1][i+1].x;
tri[m2].y[2] = ellipse[1][i+1].y;
tri[m2].z[2] = zi1;
i++;
}
}
first = FALSE;
}
/* First half is ready. Now, either close it and return or
construct the other half by simetry */
if (cone || piram || sino || hemi) { /* close the base and return */
if (sino && fabs ((zi1 - z_c) / z_c) > 0.01) {
/* bell's last slice is 1% far from base, so we add a vertical wall */
z_top = zi1; /* update z_top value */
for (n = 0; n < n_pts; n++) {
/* First triangle */
j = n_pts * (n_slice * 2 - 1) + 2 * n;
tri[j].x[0] = ellipse[1][n].x;
tri[j].y[0] = ellipse[1][n].y;
tri[j].z[0] = z_top;
tri[j].x[1] = ellipse[1][n+1].x;
tri[j].y[1] = ellipse[1][n+1].y;
tri[j].z[1] = z_top;
tri[j].x[2] = ellipse[1][n].x;
tri[j].y[2] = ellipse[1][n].y;
tri[j].z[2] = z_bot;
/* Second triangle */
j1 = n_pts * (n_slice * 2 - 1) + 2 * n + 1;
tri[j1].x[0] = ellipse[1][n+1].x;
tri[j1].y[0] = ellipse[1][n+1].y;
tri[j1].z[0] = z_top;
tri[j1].x[1] = ellipse[1][n+1].x;
tri[j1].y[1] = ellipse[1][n+1].y;
tri[j1].z[1] = z_bot;
tri[j1].x[2] = ellipse[1][n].x;
tri[j1].y[2] = ellipse[1][n].y;
tri[j1].z[2] = z_bot;
}
}
else if (sino) /* slightly change base depth to force a closed volume */
z_c = zi1;
i = n_pts * (n_slice*2 - 1) + 2 * n;
for (k = i, l = 0; k < i+n_pts; k++, l++) {
tri[k].x[0] = x0; tri[k].y[0] = y0;
tri[k].z[0] = z_c;
tri[k].x[1] = ellipse[1][l].x;
tri[k].y[1] = ellipse[1][l].y;
tri[k].z[1] = z_c;
tri[k].x[2] = ellipse[1][l+1].x;
tri[k].y[2] = ellipse[1][l+1].y;
tri[k].z[2] = z_c;
}
free ((void *)ellipse[0]);
free ((void *)ellipse[1]);
// return (n_pts*n_slice*2 + n);
return (k);
}
n_tri = n_pts * (n_slice*2 - 1);
for (j = n_tri-1, i = n_tri; j >= 0; j--, i++) {
tri[i].x[0] = tri[j].x[0]; tri[i].y[0] = tri[j].y[0];
tri[i].z[0] = z_c + (z_c - tri[j].z[0]);
tri[i].x[1] = tri[j].x[2]; tri[i].y[1] = tri[j].y[2];
tri[i].z[1] = z_c + (z_c - tri[j].z[2]);
tri[i].x[2] = tri[j].x[1]; tri[i].y[2] = tri[j].y[1];
tri[i].z[2] = z_c + (z_c - tri[j].z[1]);
}
free ((void *)ellipse[0]);
free ((void *)ellipse[1]);
n_tri = 2 * (n_pts * (n_slice*2 - 1));
return (n_tri);
}
double gaussian (double rad, double half_width) {
double y, gauss_ct;
gauss_ct = -0.5 / (half_width * half_width);
y = exp (rad * rad * gauss_ct);
return (y);
}
int cilindro (double rad_c, double height_c, double z_c, double x0, double y0, int n_pts) {
double z_top, z_bot, dfi;
int i, j, j1, n_tri;
n_tri = n_pts * 4;
circ = (struct CIRC *) calloc ((size_t) (n_pts+1), sizeof(struct CIRC));
tri = (struct TRIANG *) calloc ((size_t) (n_tri), sizeof(struct TRIANG));
dfi = (DPI/n_pts);
z_top = z_c + height_c; z_bot = z_c ;
for (i = 0; i < n_pts; i++) { /* compute circle */
circ[i].x = x0 + rad_c * cos (i*dfi);
circ[i].y = y0 + rad_c * sin (i*dfi);
}
circ[n_pts].x = circ[0].x; circ[n_pts].y = circ[0].y;
for (i = 0; i < n_pts; i++) { /* Calculates vertex of top circle */
tri[i].x[0] = x0; tri[i].y[0] = y0; tri[i].z[0] = z_top;
tri[i].x[1] = circ[i+1].x; tri[i].y[1] = circ[i+1].y;
tri[i].z[1] = z_top;
tri[i].x[2] = circ[i].x; tri[i].y[2] = circ[i].y;
tri[i].z[2] = z_top;
}
for (i = 0; i < n_pts; i++) { /* Calculates vertex of side rectangle, where each one is decomposed into two triangles */
/* First triangle */
j = 2 * i + n_pts;
tri[j].x[0] = circ[i].x; tri[j].y[0] = circ[i].y;
tri[j].z[0] = z_top;
tri[j].x[1] = circ[i+1].x; tri[j].y[1] = circ[i+1].y;
tri[j].z[1] = z_top;
tri[j].x[2] = circ[i].x; tri[j].y[2] = circ[i].y;
tri[j].z[2] = z_bot;
/* Second triangle */
j1 = 2 * i + n_pts + 1;
tri[j1].x[0] = circ[i+1].x; tri[j1].y[0] = circ[i+1].y;
tri[j1].z[0] = z_top;
tri[j1].x[1] = circ[i+1].x; tri[j1].y[1] = circ[i+1].y;
tri[j1].z[1] = z_bot;
tri[j1].x[2] = circ[i].x; tri[j1].y[2] = circ[i].y;
tri[j1].z[2] = z_bot;
}
for (i = 0; i < n_pts; i++) { /* Now the vertex of bottom circle */
j = i + 3 * n_pts;
tri[j].x[0] = x0; tri[j].y[0] = y0; tri[j].z[0] = z_bot;
tri[j].x[1] = circ[i].x; tri[j].y[1] = circ[i].y;
tri[j].z[1] = z_bot;
tri[j].x[2] = circ[i+1].x; tri[j].y[2] = circ[i+1].y;
tri[j].z[2] = z_bot;
}
free ((void *)circ);
return (n_tri);
}
int paralelo (double a, double b, double c, double z_c, double x0, double y0) {
double z_top, z_bot;
int i, n_tri = 12;
tri = (struct TRIANG *) calloc ((size_t) (n_tri), sizeof(struct TRIANG));
z_top = z_c + c; z_bot = z_c ;
/* vertex of top rectangle */
/* first triangle */
tri[0].x[0] = - a/2. + x0; tri[0].y[0] = - b/2. + y0;
tri[0].z[0] = z_top;
tri[0].x[1] = - a/2. + x0; tri[0].y[1] = b/2. + y0;
tri[0].z[1] = z_top;
tri[0].x[2] = a/2. + x0; tri[0].y[2] = b/2. + y0;
tri[0].z[2] = z_top;
/* second triangle */
tri[1].x[0] = - a/2. + x0; tri[1].y[0] = - b/2. + y0;
tri[1].z[0] = z_top;
tri[1].x[1] = a/2. + x0; tri[1].y[1] = b/2. + y0;
tri[1].z[1] = z_top;
tri[1].x[2] = a/2. + x0; tri[1].y[2] = - b/2. + y0;
tri[1].z[2] = z_top;
/* vertex of est rectangle */
/* first triangle */
tri[2].x[0] = a/2. + x0; tri[2].y[0] = - b/2. + y0;
tri[2].z[0] = z_bot;
tri[2].x[1] = a/2. + x0; tri[2].y[1] = - b/2. + y0;
tri[2].z[1] = z_top;
tri[2].x[2] = a/2. + x0; tri[2].y[2] = b/2. + y0;
tri[2].z[2] = z_top;
/* second triangle */
tri[3].x[0] = a/2. + x0; tri[3].y[0] = - b/2. + y0;
tri[3].z[0] = z_bot;
tri[3].x[1] = a/2. + x0; tri[3].y[1] = b/2. + y0;
tri[3].z[1] = z_top;
tri[3].x[2] = a/2. + x0; tri[3].y[2] = b/2. + y0;
tri[3].z[2] = z_bot;
/* vertex of north rectangle */
/* first triangle */
tri[4].x[0] = a/2. + x0; tri[4].y[0] = b/2. + y0;
tri[4].z[0] = z_bot;
tri[4].x[1] = a/2. + x0; tri[4].y[1] = b/2. + y0;
tri[4].z[1] = z_top;
tri[4].x[2] = - a/2. + x0; tri[4].y[2] = b/2. + y0;
tri[4].z[2] = z_top;
/* second triangle */
tri[5].x[0] = a/2. + x0; tri[5].y[0] = b/2. + y0;
tri[5].z[0] = z_bot;
tri[5].x[1] = - a/2. + x0; tri[5].y[1] = b/2. + y0;
tri[5].z[1] = z_top;
tri[5].x[2] = - a/2. + x0; tri[5].y[2] = b/2. + y0;
tri[5].z[2] = z_bot;
/* vertex of west rectangle */
/* first triangle */
tri[6].x[0] = - a/2. + x0; tri[6].y[0] = b/2. + y0;
tri[6].z[0] = z_bot;
tri[6].x[1] = - a/2. + x0; tri[6].y[1] = b/2. + y0;
tri[6].z[1] = z_top;
tri[6].x[2] = - a/2. + x0; tri[6].y[2] = - b/2. + y0;
tri[6].z[2] = z_top;
/* second triangle */
tri[7].x[0] = - a/2. + x0; tri[7].y[0] = b/2. + y0;
tri[7].z[0] = z_bot;
tri[7].x[1] = - a/2. + x0; tri[7].y[1] = - b/2. + y0;
tri[7].z[1] = z_top;
tri[7].x[2] = - a/2. + x0; tri[7].y[2] = - b/2. + y0;
tri[7].z[2] = z_bot;
/* vertex of south rectangle */
/* first triangle */
tri[8].x[0] = - a/2. + x0; tri[8].y[0] = - b/2. + y0;
tri[8].z[0] = z_bot;
tri[8].x[1] = - a/2. + x0; tri[8].y[1] = - b/2. + y0;
tri[8].z[1] = z_top;
tri[8].x[2] = a/2. + x0; tri[8].y[2] = - b/2. + y0;
tri[8].z[2] = z_top;
/* second triangle */
tri[9].x[0] = - a/2. + x0; tri[9].y[0] = - b/2. + y0;
tri[9].z[0] = z_bot;
tri[9].x[1] = a/2. + x0; tri[9].y[1] = - b/2. + y0;
tri[9].z[1] = z_top;
tri[9].x[2] = a/2. + x0; tri[9].y[2] = - b/2. + y0;
tri[9].z[2] = z_bot;
/* vertex of bottom rectangle */
/* first triangle */
tri[10].x[0] = - a/2. + x0; tri[10].y[0] = - b/2. + y0;
tri[10].z[0] = z_bot;
tri[10].x[1] = a/2. + x0; tri[10].y[1] = b/2. + y0;
tri[10].z[1] = z_bot;
tri[10].x[2] = - a/2. + x0; tri[10].y[2] = b/2. + y0;
tri[10].z[2] = z_bot;
/* second triangle */
tri[11].x[0] = - a/2. + x0; tri[11].y[0] = - b/2. + y0;
tri[11].z[0] = z_bot;
tri[11].x[1] = a/2. + x0; tri[11].y[1] = - b/2. + y0;
tri[11].z[1] = z_bot;
tri[11].x[2] = a/2. + x0; tri[11].y[2] = b/2. + y0;
tri[11].z[2] = z_bot;
return (12);
}
void euler (double phi, double teta, double psi, int n_pts, double x0, double y0, double z_c) {
double c_tet, s_tet, c_phi, s_phi, c_psi, s_psi, a[3][3];
double x1, y1, z1, x2, y2, z2, x3, y3, z3;
int i;
c_phi = cos (phi*D2R); s_phi = sin(phi*D2R);
c_tet = cos (teta*D2R); s_tet = sin(teta*D2R);
c_psi = cos (psi*D2R); s_psi = sin(psi*D2R);
a[0][0] = c_psi*c_phi - c_tet*s_phi*s_psi;
a[0][1] = c_psi*s_phi + c_tet*c_phi*s_psi;
a[0][2] = s_psi*s_tet;
a[1][0] = -s_psi*c_phi - c_tet*s_phi*c_psi;
a[1][1] = -s_psi*s_phi + c_tet*c_phi*c_psi;
a[1][2] = c_psi*s_tet;
a[2][0] = s_tet*s_phi;
a[2][1] = -s_tet*c_phi;
a[2][2] = c_tet;
for (i = 0; i < n_pts; i++) {
x1 = tri[i].x[0] - x0; y1 = tri[i].y[0] - y0;
z1 = tri[i].z[0] - z_c;
x2 = tri[i].x[1] - x0; y2 = tri[i].y[1] - y0;
z2 = tri[i].z[1] - z_c;
x3 = tri[i].x[2] - x0; y3 = tri[i].y[2] - y0;
z3 = tri[i].z[2] - z_c;
tri[i].x[0] = a[0][0]*x1 + a[0][1]*y1 + a[0][2]*z1 + x0;
tri[i].y[0] = a[1][0]*x1 + a[1][1]*y1 + a[1][2]*z1 + y0;
tri[i].z[0] = a[2][0]*x1 + a[2][1]*y1 + a[2][2]*z1 + z_c;
tri[i].x[1] = a[0][0]*x2 + a[0][1]*y2 + a[0][2]*z2 + x0;
tri[i].y[1] = a[1][0]*x2 + a[1][1]*y2 + a[1][2]*z2 + y0;
tri[i].z[1] = a[2][0]*x2 + a[2][1]*y2 + a[2][2]*z2 + z_c;
tri[i].x[2] = a[0][0]*x3 + a[0][1]*y3 + a[0][2]*z3 + x0;
tri[i].y[2] = a[1][0]*x3 + a[1][1]*y3 + a[1][2]*z3 + y0;
tri[i].z[2] = a[2][0]*x3 + a[2][1]*y3 + a[2][2]*z3 + z_c;
}
}
double area (int n_pts) {
/* Compute area of body */
int i;
double S, A, B, C, sup, dx0, dx1, dx2, dy0, dy1, dy2, dz0, dz1, dz2, x;
sup = 0.;
for (i = 0; i < n_pts; i++) {
dx0 = tri[i].x[1] - tri[i].x[0];
dx1 = tri[i].x[2] - tri[i].x[1];
dx2 = tri[i].x[0] - tri[i].x[2];
dy0 = tri[i].y[1] - tri[i].y[0];
dy1 = tri[i].y[2] - tri[i].y[1];
dy2 = tri[i].y[0] - tri[i].y[2];
dz0 = tri[i].z[1] - tri[i].z[0];
dz1 = tri[i].z[2] - tri[i].z[1];
dz2 = tri[i].z[0] - tri[i].z[2];
A = sqrt (dx0*dx0 + dy0*dy0 + dz0*dz0);
B = sqrt (dx1*dx1 + dy1*dy1 + dz1*dz1);
C = sqrt (dx2*dx2 + dy2*dy2 + dz2*dz2);
S = (A + B + C) / 2.;
sup += sqrt ( S*(S-A)*(S-B)*(S-C) );
}
return (sup);
}
To unsubscribe, send the message "signoff gmt-help" to [email protected]