home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c) Copyright 1993, 1994, 1995, 1996 Silicon Graphics, Inc.
- * ALL RIGHTS RESERVED
- * Permission to use, copy, modify, and distribute this software for
- * any purpose and without fee is hereby granted, provided that the above
- * copyright notice appear in all copies and that both the copyright notice
- * and this permission notice appear in supporting documentation, and that
- * the name of Silicon Graphics, Inc. not be used in advertising
- * or publicity pertaining to distribution of the software without specific,
- * written prior permission.
- *
- * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
- * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
- * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
- * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
- * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
- * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
- * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
- * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * US Government Users Restricted Rights
- * Use, duplication, or disclosure by the Government is subject to
- * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
- * (c)(1)(ii) of the Rights in Technical Data and Computer Software
- * clause at DFARS 252.227-7013 and/or in similar or successor
- * clauses in the FAR or the DOD or NASA FAR Supplement.
- * Unpublished-- rights reserved under the copyright laws of the
- * United States. Contractor/manufacturer is Silicon Graphics,
- * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
- *
- * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
- */
- #include "glu.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
-
- #include "Unitdisk.h"
-
- #define M_PI 3.14159265359
-
- const float fudge = .000001;
- const float M_2PI = 2.0 * M_PI;
-
- Unitdisk::Unitdisk()
- {
- rdivisions = 3;
- tdivisions = 10;
- points = normals = NULL;
- colors = NULL;
- points_size = normals_size = colors_size = 0;
- angle = M_PI;
- zaxis[0] = 0;
- zaxis[1] = 0;
- zaxis[2] = 1;
-
- still_in_xy = 1;
-
- sintable = costable = NULL;
- }
-
- Unitdisk::~Unitdisk()
- {
- }
-
- void Unitdisk::draw()
- {
- if (points == NULL) return;
- glNormal3f(0, 0, 1);
- if (colors == NULL) draw_nocolors();
- else if (normals == NULL) draw_colors_nonormals();
- else draw_colors_normals();
- }
-
- void Unitdisk::draw_nocolors()
- {
- int r, t, p1, p2;
- int has_n;
-
- has_n = (normals != NULL);
-
- for (t = 1; t < tdivisions; t++) {
- glBegin(GL_QUAD_STRIP);
- p1 = t * (rdivisions + 1);
- p2 = (t - 1) * (rdivisions + 1);
- for (r = 0; r <= rdivisions; r++, p1++, p2++) {
- if (has_n) glNormal3fv(normals[p1].pt);
- glTexCoord2fv(points[p1].pt);
- glVertex3fv(points[p1].pt);
- if (has_n) glNormal3fv(normals[p2].pt);
- glTexCoord2fv(points[p2].pt);
- glVertex3fv(points[p2].pt);
- }
- glEnd();
- }
-
- glBegin(GL_QUAD_STRIP);
- p1 = 0;
- p2 = (rdivisions + 1) * (tdivisions - 1);
- for (r = 0; r <= rdivisions; r++, p1++, p2++) {
- if (has_n) glNormal3fv(normals[p1].pt);
- glTexCoord2fv(points[p1].pt);
- glVertex3fv(points[p1].pt);
- if (has_n) glNormal3fv(normals[p2].pt);
- glTexCoord2fv(points[p2].pt);
- glVertex3fv(points[p2].pt);
- }
- glEnd();
- }
-
- void Unitdisk::draw_colors_nonormals()
- {
- int r, t, p1, p2;
-
- for (t = 1; t < tdivisions; t++) {
- glBegin(GL_QUAD_STRIP);
- p1 = t * (rdivisions + 1);
- p2 = (t - 1) * (rdivisions + 1);
- for (r = 0; r <= rdivisions; r++, p1++, p2++) {
- glColor4fv(colors[p1].c);
- glTexCoord2fv(points[p1].pt);
- glVertex3fv(points[p1].pt);
- glColor4fv(colors[p2].c);
- glTexCoord2fv(points[p2].pt);
- glVertex3fv(points[p2].pt);
- }
- glEnd();
- }
-
- glBegin(GL_QUAD_STRIP);
- p1 = 0;
- p2 = (rdivisions + 1) * (tdivisions - 1);
- for (r = 0; r <= rdivisions; r++, p1++, p2++) {
- glColor4fv(colors[p1].c);
- glTexCoord2fv(points[p1].pt);
- glVertex3fv(points[p1].pt);
- glColor4fv(colors[p2].c);
- glTexCoord2fv(points[p2].pt);
- glVertex3fv(points[p2].pt);
- }
- glEnd();
- }
-
- void Unitdisk::draw_colors_normals()
- {
- int r, t, p1, p2;
-
- for (t = 1; t < tdivisions; t++) {
- glBegin(GL_QUAD_STRIP);
- p1 = t * (rdivisions + 1);
- p2 = (t - 1) * (rdivisions + 1);
- for (r = 0; r <= rdivisions; r++, p1++, p2++) {
- glColor4fv(colors[p1].c);
- glNormal3fv(normals[p1].pt);
- glTexCoord2fv(points[p1].pt);
- glVertex3fv(points[p1].pt);
- glColor4fv(colors[p2].c);
- glNormal3fv(normals[p2].pt);
- glTexCoord2fv(points[p2].pt);
- glVertex3fv(points[p2].pt);
- }
- glEnd();
- }
-
- glBegin(GL_QUAD_STRIP);
- p1 = 0;
- p2 = (rdivisions + 1) * (tdivisions - 1);
- for (r = 0; r <= rdivisions; r++, p1++, p2++) {
- glColor4fv(colors[p1].c);
- glNormal3fv(normals[p1].pt);
- glTexCoord2fv(points[p1].pt);
- glVertex3fv(points[p1].pt);
- glColor4fv(colors[p2].c);
- glNormal3fv(normals[p2].pt);
- glTexCoord2fv(points[p2].pt);
- glVertex3fv(points[p2].pt);
- }
- glEnd();
- }
-
- void Unitdisk::draw_by_perimeter(int pass_colors, int pass_norms,
- int pass_tex)
- {
- int i, index, r = rdivisions + 1;
-
- if (points == NULL) return;
- if (pass_colors && colors == NULL) {
- fprintf(stderr, "Warning: No colors to draw in Unitdisk.c++");
- pass_colors = 0;
- }
- if (pass_norms && normals == NULL) {
- fprintf(stderr, "Warning: No normals to draw in Unitdisk.c++");
- pass_norms = 0;
- }
- glBegin(GL_POLYGON);
- for (i = 0, index = rdivisions; i < tdivisions; i++, index += r) {
- if (pass_colors) glColor4fv(colors[index].c);
- if (pass_norms) glNormal3fv(normals[index].pt);
- if (pass_tex) glTexCoord2fv(points[index].pt);
- glVertex3fv(points[index].pt);
- }
- glEnd();
-
- }
-
- void Unitdisk::set_angle(float new_angle)
- {
- angle = new_angle;
- }
-
- GLfloat Unitdisk::get_angle()
- {
- return angle;
- }
-
- GLfloat Unitdisk::get_radius()
- {
- return cos((M_PI - angle) / 2.0);
- }
-
- void Unitdisk::set_divisions(int new_rdivisions, int new_tdivisions)
- {
- if (tdivisions != new_tdivisions) {
- delete sintable;
- delete costable;
- sintable = costable = NULL;
- }
- if (tdivisions != new_tdivisions || rdivisions != new_rdivisions) {
- rdivisions = new_rdivisions;
- tdivisions = new_tdivisions;
- free_points();
- free_normals();
- free_colors();
- }
- }
-
- int Unitdisk::get_rdivisions()
- {
- return rdivisions;
- }
-
- int Unitdisk::get_tdivisions()
- {
- return tdivisions;
- }
-
- void Unitdisk::alloc_points()
- {
- int npoints = get_npoints();
- if (npoints > points_size) {
- delete points;
- points = new Point_b[npoints];
- points_size = npoints;
- }
- }
-
- void Unitdisk::alloc_normals()
- {
- int npoints = get_npoints();
- if (npoints > normals_size) {
- delete normals;
- normals = new Point_b[npoints];
- normals_size = npoints;
- }
- }
-
- void Unitdisk::alloc_points_normals()
- {
- alloc_points();
- alloc_normals();
- }
-
- void Unitdisk::free_points()
- {
- delete points;
- points = NULL;
- points_size = 0;
- }
-
- void Unitdisk::free_normals()
- {
- delete normals;
- normals = NULL;
- normals_size = 0;
- }
-
- void Unitdisk::free_points_normals()
- {
- free_points();
- free_normals();
- }
-
- void Unitdisk::fill_points()
- {
- alloc_points();
- fill_either(points);
- }
-
- void Unitdisk::fill_normals()
- {
- alloc_normals();
- fill_either(normals);
- }
-
- void Unitdisk::fill_points_normals()
- {
- alloc_points();
- alloc_normals();
- fill_either(points);
- fill_either(normals);
- }
-
- void Unitdisk::copy_points(Unitdisk src)
- {
- set_divisions(src.rdivisions, src.tdivisions);
- alloc_points();
- copy_either(points, src.points);
- }
-
- void Unitdisk::copy_normals(Unitdisk src)
- {
- set_divisions(src.rdivisions, src.tdivisions);
- alloc_normals();
- copy_either(normals, src.normals);
- }
-
- void Unitdisk::copy_either(Point_b *dpt, Point_b *spt) {
- int i, npoints;
- npoints = get_npoints();
- for (i = 0; i < npoints; i++, dpt++, spt++) {
- dpt->pt[0] = spt->pt[0];
- dpt->pt[1] = spt->pt[1];
- dpt->pt[2] = spt->pt[2];
- }
- }
-
- void Unitdisk::copy_normals_from_points(Unitdisk src) {
- set_divisions(src.rdivisions, src.tdivisions);
- alloc_normals();
- copy_either(normals, src.points);
- }
-
- void Unitdisk::copy_normals_from_points() {
- copy_normals_from_points(*this);
- }
-
- void Unitdisk::fill_either(Point_b *what) {
- int t, r;
- int i;
-
- fill_either_strip1(what);
- if (sintable == NULL) fill_trig_tables();
- i = rdivisions + 1;
- for (t = 1; t < tdivisions; t++) {
- for (r = 0; r <= rdivisions; r++) {
- what[i].pt[0] = costable[t] * what[r].pt[0];
- what[i].pt[1] = sintable[t] * what[r].pt[0];
- what[i].pt[2] = what[r].pt[2];
- i++;
- }
- }
- }
-
- void Unitdisk::fill_points_strip1()
- {
- alloc_points();
- fill_either_strip1(points);
- }
-
- void Unitdisk::fill_either_strip1(Point_b *what) {
- float radius, rinc;
- int r;
-
- rinc = get_radius() / (float)rdivisions;
- radius = 0.0;
- for (r = 0; r <= rdivisions; r++, radius += rinc) {
- what[r].pt[0] = radius;
- what[r].pt[1] = 0;
- // Round-off error avoidance hack
- what[r].pt[2] = 1.0 - what[r].pt[0]*what[r].pt[0];
- if (what[r].pt[2] > 0.0) what[r].pt[2] = sqrt(what[r].pt[2]);
- else what[r].pt[2] = 0.0;
- }
- }
-
- void Unitdisk::translate(Point_b trans)
- {
- int i, npoints;
- npoints = get_npoints();
- for (i = 0; i < npoints; i++) {
- points[i].pt[0] += trans.pt[0];
- points[i].pt[1] += trans.pt[1];
- points[i].pt[2] += trans.pt[2];
- }
- }
-
- void Unitdisk::scale(float s)
- {
- int i, npoints;
- npoints = get_npoints();
- for (i = 0; i < npoints; i++) {
- points[i].pt[0] *= s;
- points[i].pt[1] *= s;
- points[i].pt[2] *= s;
- }
- }
-
- void Unitdisk::scale_translate(float s, Point_b trans)
- {
- int i, npoints;
- npoints = get_npoints();
- for (i = 0; i < npoints; i++) {
- points[i].pt[0] = points[i].pt[0]*s + trans.pt[0];
- points[i].pt[1] = points[i].pt[1]*s + trans.pt[1];
- points[i].pt[2] = points[i].pt[2]*s + trans.pt[2];
- }
- }
-
- int Unitdisk::get_npoints()
- {
- return (rdivisions + 1) * tdivisions;
- }
-
- void Unitdisk::project()
- {
- int i, npoints;
-
- if (normals == NULL) {
- fprintf(stderr, "Warning: No normals defined when project() called.\n");
- fill_normals();
- }
- if (points == NULL) fill_points();
- npoints = get_npoints();
- for (i = 0; i < npoints; i++) {
- /* I'm not sure quite what the justification for this is, but it
- * seems to work */
- if (normals[i].pt[2] < 0.0) normals[i].pt[2] = -normals[i].pt[2];
- points[i] = points[i].project_direction(normals[i]);
- }
- }
-
- void Unitdisk::project(Point_b projpt)
- {
- int i, npoints = get_npoints();
- float x, y, z;
- Point_b *pt;
-
- if (points == NULL) fill_points();
- x = projpt.pt[0];
- y = projpt.pt[1];
- z = projpt.pt[2];
- pt = points;
- for (i = 0; i < npoints; i++, pt++) pt->project_self(x, y, z);
- }
-
- void Unitdisk::project_borrow_points(Unitdisk src)
- {
- int i, npoints = get_npoints();
- Point_b *pt, *spt, *sn;
- spt = src.points;
- sn = normals;
- alloc_points();
- pt = points;
- for (i = 0; i < npoints; i++, pt++, spt++, sn++) {
- /* I'm not sure quite what the justification for this is, but it
- * seems to work */
- if (normals[i].pt[2] < 0.0) normals[i].pt[2] = -normals[i].pt[2];
- pt->compute_projected(spt->pt[0], spt->pt[1], spt->pt[2],
- sn->pt[0], sn->pt[1], sn->pt[2]);
- }
- }
-
- void Unitdisk::refract_normals(Point_b light, GLfloat I)
- {
- Point_b dlight;
- float cos1, sin1, cos2, sin2;
- int use_normals;
- int r, t, i;
-
- if (points == NULL) {
- fprintf(stderr, "Attempting to refract without points.\n");
- fill_normals();
- }
-
- use_normals = (normals != NULL);
- alloc_normals();
-
- /* Do the theta = 0 diagonal */
- for (r = 0; r <= rdivisions; r++) {
- /* Find the original normal - use the unit of the points if there are
- * no normals */
- if (!use_normals) normals[r] = points[r].unit();
-
- /* Compute the direction to the light */
- dlight = (light - points[r]).unit();
-
- /* Compute the cosine and the sine of the original angle */
- cos1 = dlight.dot(normals[r]);
- sin1 = 1.0 - cos1*cos1;
- if (sin1 <= 0.0) continue;
- sin1 = sqrt(sin1);
-
- /* Compute the cosine and the sine of the new angle */
- sin2 = sin1 / I;
- cos2 = sqrt(1.0 - sin2*sin2);
-
- /* Rotate the normal by the new sine and cosine */
- normals[r] = normals[r].rotate_abouty(cos2, -sin2);
- }
-
- /* Copy the rest of the rows from the current row */
- i = rdivisions + 1;
- if (sintable == NULL) fill_trig_tables();
- for (t = 1; t < tdivisions; t++) {
- for (r = 0; r <= rdivisions; r++) {
- normals[i].pt[0] = costable[t] * normals[r].pt[0];
- normals[i].pt[1] = sintable[t] * normals[r].pt[0];
- normals[i].pt[2] = normals[r].pt[2];
- i++;
- }
- }
-
- }
-
- void Unitdisk::face_direction(Point_b d)
- {
- face_direction(d, *this);
- }
-
- void Unitdisk::face_direction(Point_b d, Unitdisk src)
- {
- Point_b *spt, *dpt, *sn, *dn;
- float sin1, cos1;
- float x;
- int npoints, i;
-
- if (d.pt[1]) {
- fprintf(stderr,
- "Internal error: Can't face in direction not in xz plane.");
- return;
- }
-
- cos1 = d.pt[2];
- sin1 = d.pt[0];
-
- if (sin1 * sin1 > fudge) {
- spt = src.points;
- dpt = points;
- sn = src.normals;
- dn = normals;
- /* Change this to be seperate loops for points&&normals, points, normals
- * (faster than testing every iteration */
- npoints = get_npoints();
- for (i = 0; i < npoints; i++) {
- if (points != NULL) {
- x = spt->pt[0];
- dpt->pt[0] = x*cos1 + spt->pt[2]*sin1;
- dpt->pt[1] = spt->pt[1];
- dpt->pt[2] = -x*sin1 + spt->pt[2]*cos1;
- spt++; dpt++;
- }
- if (normals != NULL) {
- x = sn->pt[0];
- dn->pt[0] = x*cos1 + sn->pt[2]*sin1;
- dn->pt[1] = sn->pt[1];
- dn->pt[2] = -x*sin1 + sn->pt[2]*cos1;
- sn++; dn++;
- }
- }
- } else if (points != NULL && points != src.points) {
- copy_points(src);
- if (normals != NULL) copy_normals(src);
- }
- }
-
- void Unitdisk::alloc_colors()
- {
- int ncolors = get_npoints();
- if (ncolors > colors_size) {
- delete colors;
- colors = new Color[ncolors];
- colors_size = ncolors;
- }
- }
-
- void Unitdisk::map_normals_to_colors()
- {
- int t, r;
- int i;
-
- if (normals == NULL) fill_normals();
- alloc_colors();
- i = 0;
- for (t = 1; t <= tdivisions; t++) {
- for (r = 0; r <= rdivisions; r++) {
- colors[i] *= normals[r].pt[2];
- colors[i].c[3] = 1;
- i++;
- }
- }
- }
-
- void Unitdisk::map_z_to_colors()
- {
- int i, npoints = get_npoints();
-
- if (points == NULL) {
- fprintf(stderr, "Warning: no points defined in map_z_to_colors()\n");
- fill_points();
- }
-
- alloc_colors();
- for (i = 0; i < npoints; i++) {
- colors[i] = points[i].pt[2];
- colors[i].c[3] = 1;
- }
- }
-
- void Unitdisk::scale_alpha_by_z()
- {
- int i, npoints = get_npoints();
-
- if (colors == NULL) alloc_colors();
- if (points == NULL) {
- alloc_points();
- fill_points();
- }
- for (i = 0; i < npoints; i++) colors[i].c[3] *= points[i].pt[2];
- }
-
- void Unitdisk::scale_colors_by_z()
- {
- int i, npoints = get_npoints();
-
- if (colors == NULL) alloc_colors();
- if (points == NULL) {
- alloc_points();
- fill_points();
- }
- for (i = 0; i < npoints; i++) colors[i] *= points[i].pt[2];
- }
-
- void Unitdisk::scale_colors_by_normals(Point_b light)
- {
- scale_colors_by_normals(light, *this);
- }
-
- void Unitdisk::scale_colors_by_normals(Point_b light, Unitdisk src_normals)
- {
- scale_colors_by_either(light, src_normals.normals);
- }
-
- void Unitdisk::scale_colors_by_points(Point_b light, Unitdisk src_points)
- {
- scale_colors_by_either(light, src_points.points);
- }
-
- void Unitdisk::scale_colors_by_either(Point_b light, Point_b *what)
- {
- int t, r;
- int i;
- if (what == NULL) {
- fprintf(stderr, "Scaling colors to NULL pointer.\n");
- return;
- }
- if (light.pt[0] || light.pt[1] || light.pt[2] < 0.0) {
- fprintf(stderr, "Light not on z axis in scale_colors_by_normals.\n");
- }
-
- alloc_colors();
- for (r = 0; r <= rdivisions; r++)
- colors[r] *= what[r].dot(light);
- i = rdivisions + 1;
- for (t = 1; t < tdivisions; t++) {
- for (r = 0; r <= rdivisions; r++) {
- colors[i] = colors[r];
- i++;
- }
- }
- }
-
- void Unitdisk::set_colors(Color c)
- {
- Color *dst;
- int i, npoints = get_npoints();
- alloc_colors();
- dst = colors;
- for (i = 0; i < npoints; i++, dst++) {
- dst->c[0] = c.c[0];
- dst->c[1] = c.c[1];
- dst->c[2] = c.c[2];
- dst->c[3] = c.c[3];
- }
- }
-
- void Unitdisk::add_colors(Color c)
- {
- int i, npoints = get_npoints();
- alloc_colors();
- for (i = 0; i < npoints; i++) colors[i] += c;
- }
-
- void Unitdisk::free_colors()
- {
- delete colors;
- colors = NULL;
- colors_size = 0;
- }
-
- inline float Unitdisk::area_triangle(Point_b a, Point_b b, Point_b c)
- {
- return (((a.pt[0]*b.pt[1] + b.pt[0]*c.pt[1] + c.pt[0]*a.pt[1]) -
- (a.pt[1]*b.pt[0] + b.pt[1]*c.pt[0] + c.pt[1]*a.pt[0])) * .5);
- }
-
- inline float Unitdisk::area_triangle(GLfloat *a, GLfloat *b,
- GLfloat *c)
- {
- return (((a[0]*b[1] + b[0]*c[1] + c[0]*a[1]) -
- (a[1]*b[0] + b[1]*c[0] + c[1]*a[0])) * .5);
- }
-
- inline float Unitdisk::area_2triangle(GLfloat *a, GLfloat *b,
- GLfloat *c)
- {
- return ((a[0]*b[1] + b[0]*c[1] + c[0]*a[1]) -
- (a[1]*b[0] + b[1]*c[0] + c[1]*a[0]));
- }
-
- void Unitdisk::scale_colors_by_darea(Unitdisk disk)
- {
- int pt1, pt2, pt3;
- int t, r, i;
- int npoints = get_npoints();
- float *rproducts1, *tproducts1, *rproducts2, *tproducts2;
- float area1, area2;
-
- rproducts1 = new float[npoints];
- tproducts1 = new float[npoints];
- rproducts2 = new float[npoints];
- tproducts2 = new float[npoints];
-
- /* Compute the products of the segments which make up the disk -
- * these will later be used in the area calculations */
- i = 0;
- for (t = 0; t < tdivisions; t++) {
- for (r = 0; r < rdivisions; r++) {
- pt1 = i;
- pt2 = i + 1;
- rproducts1[i] = (points[pt1].pt[0]*points[pt2].pt[1] -
- points[pt1].pt[1]*points[pt2].pt[0]);
- rproducts2[i] = (disk.points[pt1].pt[0]*disk.points[pt2].pt[1] -
- disk.points[pt1].pt[1]*disk.points[pt2].pt[0]);
- pt2 = ((t+1)%tdivisions)*(rdivisions + 1) + r;
- tproducts1[i] = (points[pt1].pt[0]*points[pt2].pt[1] -
- points[pt1].pt[1]*points[pt2].pt[0]);
- tproducts2[i] = (disk.points[pt1].pt[0]*disk.points[pt2].pt[1] -
- disk.points[pt1].pt[1]*disk.points[pt2].pt[0]);
- i++;
- }
- pt1 = i;
- pt2 = ((t+1)%tdivisions)*(rdivisions + 1) + r;
- tproducts1[i] = (points[pt1].pt[0]*points[pt2].pt[1] -
- points[pt1].pt[1]*points[pt2].pt[0]);
- tproducts2[i] = (disk.points[pt1].pt[0]*disk.points[pt2].pt[1] -
- disk.points[pt1].pt[1]*disk.points[pt2].pt[0]);
- i++;
- }
-
- /* Compute the area at the center of the disk */
- area1 = area2 = 0.0;
- r = 1;
- for (t = 0; t <= tdivisions; t++) {
- pt1 = (t%tdivisions)*(rdivisions+1) + r;
- area1 += tproducts1[pt1];
- area2 += tproducts2[pt1];
- }
- if (area1 != 0.0) area1 = fabs(area2 / area1);
- for (t = 0; t < tdivisions; t++) {
- colors[t*(rdivisions+1)] *= area1;
- }
-
- for (t = 0; t < tdivisions; t++) {
- for (r = 1; r < rdivisions; r++) {
- pt1 = (t ? t-1 : tdivisions-1)*(rdivisions+1) + r - 1;
- pt3 = t*(rdivisions + 1) + r - 1;
- pt2 = ((t+1) % tdivisions)*(rdivisions+1) + r - 1;
- area1 = rproducts1[pt1] + rproducts1[pt1 + 1];
- area1 += tproducts1[pt1 + 2] + tproducts1[pt3 + 2];
- area1 -= rproducts1[pt2 + 1] + rproducts1[pt2];
- area1 -= tproducts1[pt3] + tproducts1[pt1];
- area2 = rproducts2[pt1] + rproducts2[pt1 + 1];
- area2 += tproducts2[pt1 + 2] + tproducts2[pt3 + 2];
- area2 -= rproducts2[pt2 + 1] + rproducts2[pt2];
- area2 -= tproducts2[pt3] + tproducts2[pt1];
- if (area1 != 0.0) area1 = fabs(area2 / area1);
- colors[pt3 + 1] *= area1;
- }
- }
-
- /* Compute the area around the outside of the disk */
- r = rdivisions;
- for (t = 0; t < tdivisions; t++) {
- pt1 = (t ? t-1 : tdivisions-1)*(rdivisions+1) + r - 1;
- pt3 = t*(rdivisions + 1) + r - 1;
- pt2 = ((t+1) % tdivisions)*(rdivisions+1) + r - 1;
- area1 = rproducts1[pt1];
- area1 += tproducts1[pt1 + 1] + tproducts1[pt3 + 1];
- area1 -= rproducts1[pt2];
- area1 -= tproducts1[pt1] + tproducts1[pt3];
- area2 = rproducts2[pt1];
- area2 += tproducts2[pt1 + 1] + tproducts2[pt3 + 1];
- area2 -= rproducts2[pt2];
- area2 -= tproducts2[pt1] + tproducts2[pt3];
- if (area1 != 0.0) area1 = fabs(area2 / area1);
- colors[pt3 + 1] *= area1;
- }
-
-
- delete rproducts1;
- delete tproducts1;
- delete rproducts2;
- delete tproducts2;
- }
-
- void Unitdisk::fill_trig_tables()
- {
- int t;
-
- delete sintable;
- delete costable;
- sintable = new float[tdivisions];
- costable = new float[tdivisions];
- for (t = 0; t < tdivisions; t++) {
- costable[t] = cos(M_2PI * (float)t / (float)tdivisions);
- sintable[t] = sin(M_2PI * (float)t / (float)tdivisions);
- }
- }
-