/*****************************************************************************1*2* Elmer, A Finite Element Software for Multiphysical Problems3*4* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland5*6* This program is free software; you can redistribute it and/or7* modify it under the terms of the GNU General Public License8* as published by the Free Software Foundation; either version 29* of the License, or (at your option) any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program (in file fem/GPL-2); if not, write to the18* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,19* Boston, MA 02110-1301, USA.20*21*****************************************************************************/2223/*******************************************************************************24*25* Graphics utilities Part II. OpenGL is being called.26*27*******************************************************************************28*29* Author: Juha Ruokolainen30*31* Address: CSC - IT Center for Science Ltd.32* Keilaranta 14, P.O. BOX 40533* 02101 Espoo, Finland34* Tel. +358 0 457 272335* Telefax: +358 0 457 230236* EMail: [email protected]37*38* Date: 26 Sep 199539*40* Modified by:41*42* Date of modification:43*44* $Id: gutil2.c,v 1.3 2003/02/06 09:37:50 jpr Exp $45*46* $Log: gutil2.c,v $47* Revision 1.3 2003/02/06 09:37:50 jpr48* *** empty log message ***49*50* Revision 1.2 1998/07/31 13:36:58 jpr51*52* Added id, started log.53*54*55******************************************************************************/56#include "../elmerpost.h"5758static int GRA_SphereQuality=3,GRA_SphereInitDone=FALSE;5960#define GRA_MAX_QUALITY 326162static double GRA_CosA[4*GRA_MAX_QUALITY];63static double GRA_SinA[4*GRA_MAX_QUALITY];64static double GRA_CosB[4*GRA_MAX_QUALITY];65static double GRA_SinB[4*GRA_MAX_QUALITY];6667/*******************************************************************************68*69* Name: gra_sphere_quality70*71* Purpose: initialize internal cos & sin tables with given resolution72*73* Parameters:74*75* Input: (int) quality factor76*77* Output: none78*79* Return value: void80*81******************************************************************************/82void gra_sphere_quality(int quality)83{84int i,j,Division;85double a;8687if ( GRA_SphereInitDone )88if ( GRA_SphereQuality == quality ) return;8990if ( quality > GRA_MAX_QUALITY ) quality = GRA_MAX_QUALITY;91else if ( quality < 1 ) quality = 1;9293GRA_SphereQuality = quality;9495Division = 4*quality;9697for( i=0; i<Division; i++ )98{99a = 2.0*M_PI*i/(double)Division;100GRA_CosA[i] = cos(a);101GRA_SinA[i] = sin(a);102}103GRA_CosA[i] = GRA_CosA[0];104GRA_SinA[i] = GRA_SinA[0];105106for( i=-Division/2,j=0; i<=Division/2; i+=2, j++ )107{108a = M_PI*i/(double)Division;109GRA_CosB[j] = cos(a);110GRA_SinB[j] = sin(a);111}112113GRA_SphereInitDone = TRUE;114}115116/*******************************************************************************117*118* Name: gra_vector_to_angles119*120* Purpose: return angles about x and y axis to rotate x-axis121* to given vector122*123* Parameters:124*125* Input: (double vx,vy,vz) first end point126* (double *px,*py,*pz) second end point127*128* Output: (double *px,*py) computed angles129*130* Return value: void131*132******************************************************************************/133void gra_vector_to_angles(double vx,double vy,double vz,double *px,double *py,double *pz,double r)134{135double a,b,x,y,z,RadToDeg=180.0/M_PI;136137x = (*px-vx)*r;138y = (*py-vy)*r;139z = (vz-*pz)*r;140141b = atan2(y,z);142143r = y*sin(b) + z*cos(b);144a = atan2(r,x);145146*px = RadToDeg*b;147*py = RadToDeg*a;148*pz = 0.0;149}150151/*******************************************************************************152*153* Name: gra_sphere154*155* Purpose: draw sphere centered at a point, with given color and156* radius157*158* Parameters:159*160* Input: (double x,y,z) sphere center point161* (double f) color162* (double r) radius163*164* Output: graphics165*166* Return value: void167*168******************************************************************************/169void gra_sphere(double x,double y,double z,double f,double r)170{171int Division = 4*GRA_SphereQuality;172int i,j;173174if ( !GRA_SphereInitDone ) gra_sphere_quality( GRA_SphereQuality );175176glPushMatrix();177178glTranslatef(x,y,z);179glScalef(r,r,r);180181for( i=0; i<Division/2; i++ )182{183glBegin(GL_QUAD_STRIP);184x = GRA_CosB[i];185y = 0.0;186z = GRA_SinB[i];187188glTexCoord1d( f );189glNormal3f(-x,-y,-z);190glVertex3f(x,y,z);191192x = GRA_CosB[i+1];193y = 0.0;194z = GRA_SinB[i+1];195196glTexCoord1d( f );197glNormal3d( -x,-y,-z );198glVertex3d( x,y,z );199200for( j=1; j<=Division; j++ )201{202x = GRA_CosA[j]*GRA_CosB[i];203y = GRA_SinA[j]*GRA_CosB[i];204z = GRA_SinB[i];205206glTexCoord1d( f );207glNormal3d( -x,-y,-z );208glVertex3d( x,y,z );209210x = GRA_CosA[j]*GRA_CosB[i+1];211y = GRA_SinA[j]*GRA_CosB[i+1];212z = GRA_SinB[i+1];213214glTexCoord1d( f );215glNormal3d( -x,-y,-z );216glVertex3d( x,y,z );217}218glEnd();219}220221glPopMatrix();222223glNormal3d( 0.0,0.0,1.0 );224}225226/*******************************************************************************227*228* Name: gra_point229*230* Purpose: draw point with given color and radius231*232* Parameters:233*234* Input: (double x,y,z) sphere center point235* (double f) color236* (double r) radius237*238* Output: graphics239*240* Return value: void241*242******************************************************************************/243void gra_point(double x,double y,double z,double f,double r)244{245glTexCoord1d( f );246glVertex3d( x,y,z );247}248249/*******************************************************************************250*251* Name: gra_cylinder252*253* Purpose: draw cylinder between points given254*255* Parameters:256*257* Input: (double x0,y0,z0) first end point coordinates258* (double f0) first end point color259* (double x1,y1,z1)) second end point coordinates260* (double f1) second end point color261* (double R) cylinder radius262*263* Output: graphics264*265* Return value: void266*267******************************************************************************/268void gra_cylinder(double x0,double y0,double z0,double f0,double x1,double y1,double z1,double f1,double R)269{270double ax,ay,az,s;271272int i,j;273274if ( !GRA_SphereInitDone ) gra_sphere_quality( GRA_SphereQuality );275276ax = x1;277ay = y1;278az = z1;279x1 = ax - x0;280y1 = ay - y0;281z1 = az - z0;282s = sqrt( x1*x1+y1*y1+z1*z1 );283if ( s < 1.0e-10 ) return;284285gra_vector_to_angles( x0,y0,z0,&ax,&ay,&az,1/s );286287glPushMatrix();288289glTranslated( x0,y0,z0 );290291glRotated( ax,1.0,0.0,0.0 );292glRotated( ay,0.0,1.0,0.0 );293294glScaled( s,R,R );295296glBegin(GL_QUAD_STRIP);297298glTexCoord1d( f0 );299glNormal3d( 0.0,0.0,1.0 );300glVertex3d( 0.0,0.0,1.0 );301302glTexCoord1d( f1 );303glVertex3d( 1.0,0.0,1.0 );304305for( j=1; j<=GRA_SphereQuality*4;j++ )306{307y0 = GRA_SinA[j];308z0 = GRA_CosA[j];309310glTexCoord1d( f0 );311glNormal3d( 0.0,y0,z0 );312glVertex3d( 0.0,y0,z0 );313314glTexCoord1d( f1 );315glVertex3d( 1.0,y0,z0 );316}317318glEnd();319320glPopMatrix();321322glNormal3d( 0.0,0.0,1.0 );323}324325/*******************************************************************************326*327* Name: gra_cone328*329* Purpose: draw a cone between points given330*331* Parameters:332*333* Input: (double x0,y0,z0) first end point coordinates334* (double f0) first end point color335* (double R0) first end point radius336* (double x1,y1,z1)) second end point coordinates337* (double f1) second end point color338* (double R1) second end point radius339*340* Output: graphics341*342* Return value: void343*344******************************************************************************/345void gra_cone(double x0,double y0,double z0,double f0,double R0,double x1,double y1,double z1,double f1,double R1)346{347double ax,ay,az,r,s;348int i,j;349350if ( !GRA_SphereInitDone ) gra_sphere_quality(GRA_SphereQuality);351352ax = x1;353ay = y1;354az = z1;355356x1 = ax - x0;357y1 = ay - y0;358z1 = az - z0;359r = sqrt( x1*x1+y1*y1+z1*z1 );360if ( r < 1.0E-10 ) return;361362gra_vector_to_angles( x0,y0,z0,&ax,&ay,&az,1/r );363364glPushMatrix();365366glTranslated(x0,y0,z0);367368glRotated( ax,1.0,0.0,0.0 );369glRotated( ay,0.0,1.0,0.0 );370371glScaled( r,1.0,1.0 );372373s = sqrt(1+(R0-R1)*(R0-R1));374s = 1/s;375376#define NORMAL(x,y,z) glNormal3d(s*(x),s*(y),s*(z))377378glBegin(GL_QUAD_STRIP);379380NORMAL( R0-R1,0.0,1.0 );381glTexCoord1d( f0 );382glVertex3d( 0.0,0.0,R0 );383384NORMAL( R0-R1,0.0,1.0 );385glTexCoord1d( f1 );386glVertex3d( 1.0,0.0,R1 );387388for( j=1; j<=GRA_SphereQuality*4;j++ )389{390y0 = GRA_SinA[j];391z0 = GRA_CosA[j];392393NORMAL( R0-R1,y0,z0 );394395glTexCoord1d( f0 );396glVertex3d( 0.0,R0*y0,R0*z0 );397398glTexCoord1d( f1 );399glVertex3d( 1.0,R1*y0,R1*z0 );400}401402glEnd();403404#undef NORMAL405406glPopMatrix();407408glNormal3d( 0.0,0.0,1.0 );409}410411412