⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmath.c

📁 这是一个相当棒的Linux下的台球游戏
💻 C
字号:
/* vmath.c****    some vector mathematics and structures (float or double)**    Copyright (C) 2001  Florian Berger**    Email:  harpin_floh@yahoo.de,  florian.berger@jk.uni-linz.ac.at****    This program is free software; you can redistribute it and/or modify**    it under the terms of the GNU General Public License Version 2 as**    published by the Free Software Foundation;****    This program is distributed in the hope that it will be useful,**    but WITHOUT ANY WARRANTY; without even the implied warranty of**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the**    GNU General Public License for more details.****    You should have received a copy of the GNU General Public License**    along with this program; if not, write to the Free Software**    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***/#include <stdlib.h> // exit(1)#include <stdio.h>#include <string.h>#include <math.h>#include "vmath.h"void outline_copy(struct Outline os, struct Outline * od){    int i;    if( od->shnr != os.shnr ) {        if (od->shnr!=0) free(od->sh);        od->sh = (struct Shape *)malloc( os.shnr*sizeof(struct Shape) );        for(i=0;i<os.shnr;i++){            od->sh[0].pnr=0;        }    }    od->shnr = os.shnr;    for(i=0;i<os.shnr;i++){        shape_copy( os.sh[i], &(od->sh[i]) );    }}void shape_copy( struct Shape shs, struct Shape *shd ){int i;   if( shd->pnr != shs.pnr ) {      if (shd->pnr!=0) free(shd->p);      shd->p = (struct Vect *)malloc( shs.pnr*sizeof(struct Vect) );   }   shd->pnr = shs.pnr;   for(i=0;i<shs.pnr;i++) shd->p[i]=shs.p[i];}void shape_flip( struct Shape *sh ){    int i;    struct Vect dummy;    for(i=0;i<sh->pnr/2;i++){        dummy=sh->p[i];        sh->p[i]=sh->p[sh->pnr-1-i];        sh->p[sh->pnr-1-i]=dummy;    }}void shape_trans( struct Shape *s, struct Vect t ){int i;   for(i=0;i<s->pnr;i++){      s->p[i].x+=t.x;      s->p[i].y+=t.y;      s->p[i].z+=t.z;   }}struct Vect vec_cross( struct Vect v1, struct Vect v2 ){struct Vect vr;   vr.x = v1.y * v2.z - v2.y * v1.z;   vr.y = v1.z * v2.x - v2.z * v1.x;   vr.z = v1.x * v2.y - v2.x * v1.y;   return vr;}VMfloat vec_mul( struct Vect v1, struct Vect v2 ){ return( v1.x*v2.x + v1.y*v2.y + v1.z*v2.z ); }struct Vect vec_diff( struct Vect v1, struct Vect v2 ){struct Vect vr;   vr.x = v1.x - v2.x;   vr.y = v1.y - v2.y;   vr.z = v1.z - v2.z;   return vr;}struct Vect vec_add( struct Vect v1, struct Vect v2 ){struct Vect vr;   vr.x = v1.x + v2.x;   vr.y = v1.y + v2.y;   vr.z = v1.z + v2.z;   return vr;}struct Vect vec_scale( struct Vect v1, VMfloat scale ){struct Vect vr;   vr.x = v1.x * scale;   vr.y = v1.y * scale;   vr.z = v1.z * scale;   return vr;}struct Vect vec_rotate( struct Vect v1, struct Vect ang ){    struct Vect vr;    vr=v1;    rot_ax( vec_unit(ang), &vr, 1, vec_abs(ang) );    return(vr);}VMfloat vec_abs( struct Vect v ){ return( sqrt( v.x*v.x + v.y*v.y + v.z*v.z ) ); }VMfloat vec_abssq( struct Vect v ){ return( v.x*v.x + v.y*v.y + v.z*v.z ); }struct Vect vec_unit( struct Vect v ){struct Vect vr; VMfloat l;   l=vec_abs(v);   if(fabs(l)>1.0E-50){       vr.x=v.x/l;       vr.y=v.y/l;       vr.z=v.z/l;   } else {       vr.x=0.0;       vr.y=0.0;       vr.z=0.0;   }   return vr;}int vec_equal( struct Vect v1, struct Vect v2 ){   return ( v1.x==v2.x && v1.y==v2.y && v1.z==v2.z );}int vec_nearly_equal( struct Vect v1, struct Vect v2, VMfloat tolerance ){    return ( fabs(v1.x-v2.x)<tolerance &&             fabs(v1.y-v2.y)<tolerance &&             fabs(v1.z-v2.z)<tolerance );}struct Vect vec_xyz( VMfloat x, VMfloat y, VMfloat z ){ struct Vect vr;   vr.x=x; vr.y=y; vr.z=z;   return vr;}struct Vect  vec_ex(){ return(vec_xyz(1.0,0.0,0.0)); }struct Vect  vec_ey(){ return(vec_xyz(0.0,1.0,0.0)); }struct Vect  vec_ez(){ return(vec_xyz(0.0,0.0,1.0)); }struct Vect  vec_null(){ return(vec_xyz(0.0,0.0,0.0)); }void shape_rot_ax( struct Vect ax, struct Shape *s, struct Vect m, VMfloat phi,	     struct Vect nax, VMfloat sc_x, VMfloat sc_y, VMfloat sc_z ){ struct Vect bx,by,bz; // base  struct Vect dp,dp2;  VMfloat sinphi,cosphi;  int i;//   printf("rotax  ");//   printf("ax=%lf,%lf,%lf  ", ax.x, ax.y, ax.z);//   printf("phi=%lf  ", phi);      if ( phi !=0.0 && vec_abs(ax)>0.0 ){         bz = vec_unit( ax );      bx = vec_unit( nax );      by = vec_cross(bz,bx);         sinphi=sin(phi);      cosphi=cos(phi);         for( i=0; i<s->pnr; i++ ){         s->p[i] = vec_diff( s->p[i], m );         // transform into axis-system         dp.x = vec_mul( s->p[i], bx ) * sc_x;         dp.y = vec_mul( s->p[i], by ) * sc_y;         dp.z = vec_mul( s->p[i], bz ) * sc_z;            dp2.x = dp.x*cosphi - dp.y*sinphi;         dp2.y = dp.y*cosphi + dp.x*sinphi;         dp2.z = dp.z;               // retransform back         s->p[i].x = dp2.x * bx.x + dp2.y * by.x + dp2.z * bz.x;         s->p[i].y = dp2.x * bx.y + dp2.y * by.y + dp2.z * bz.y;         s->p[i].z = dp2.x * bx.z + dp2.y * by.z + dp2.z * bz.z;         s->p[i] = vec_add( s->p[i], m );      }         }//   printf("rotaxed\n");   }void rot_ax( struct Vect ax, struct Vect *v, int nr, VMfloat phi ){ struct Vect bx,by,bz; // base  struct Vect dp,dp2, nax;  VMfloat sinphi,cosphi;  int i;//   printf("rotax  ");//   printf("ax=%lf,%lf,%lf  ", ax.x, ax.y, ax.z);//   printf("phi=%lf  ", phi);      if ( phi !=0.0 && vec_abs(ax)>0.0 ){      bz = vec_unit( ax );      if( fabs(bz.x) <= fabs(bz.y) && fabs(bz.x) <= fabs(bz.z) ) nax=vec_xyz(1.0,0.0,0.0);      if( fabs(bz.y) <= fabs(bz.z) && fabs(bz.y) <= fabs(bz.x) ) nax=vec_xyz(0.0,1.0,0.0);      if( fabs(bz.z) <= fabs(bz.x) && fabs(bz.z) <= fabs(bz.y) ) nax=vec_xyz(0.0,0.0,1.0);      bx = vec_unit( vec_diff( nax, vec_scale(bz,vec_mul(nax,bz)) ) );      by = vec_cross(bz,bx);         sinphi=sin(phi);      cosphi=cos(phi);         for( i=0; i<nr; i++ ){//         v[i] = vec_diff( v[i], m );         // transform into axis-system         dp.x = vec_mul( v[i], bx );         dp.y = vec_mul( v[i], by );         dp.z = vec_mul( v[i], bz );            dp2.x = dp.x*cosphi - dp.y*sinphi;         dp2.y = dp.y*cosphi + dp.x*sinphi;         dp2.z = dp.z;               // retransform back         v[i].x = dp2.x * bx.x + dp2.y * by.x + dp2.z * bz.x;         v[i].y = dp2.x * bx.y + dp2.y * by.y + dp2.z * bz.y;         v[i].z = dp2.x * bx.z + dp2.y * by.z + dp2.z * bz.z;      }         }   }struct Vect  meshpt_nr( struct Point * plist, int index ){    int i;    struct Point * act;    for( i=0,act=plist ; i<index && act!=0 ; i++,act=act->next );    if( act==0 ){        fprintf(stderr,"meshpt_nr: error: index overflow (%d)\n",index);    }    return act->pos;}int remove_idle_points( struct Shape * sh, struct Shape * shd )/* returns # of points removed */{    int i, in, id, removenr;    id=0;    for( i=0 ; i<sh->pnr ; i++ ){//        fprintf(stderr,"%d\n",i);        in=i+1; if( in >= sh->pnr ) in=0;        if( !vec_nearly_equal( sh->p[in], sh->p[i], 1E-1 ) ){            shd->p[id] = sh->p[i];            id++;        } else {            fprintf(stderr,"removed point #%d\n",i);        }    }    removenr = sh->pnr -id;    shd->pnr=id;    return ( removenr );}VMfloat vec_angle( struct Vect v1, struct Vect v2 )/* returns positive angle between 0 and M_PI */{    return( acos(vec_mul( vec_unit(v1), vec_unit(v2) )) );}struct Vect vec_proj( struct Vect v1, struct Vect v2 ){    static VMfloat v2ls;    v2ls = v2.x*v2.x + v2.y*v2.y + v2.z*v2.z;    if( v2ls > 0.0 ){        return( vec_scale( v2, vec_mul(v1,v2)/v2ls ) );    } else {        return( v1 );    }}struct Vect vec_ncomp( struct Vect v1, struct Vect v2 ){    return( vec_diff(v1,vec_proj(v1,v2)) );}VMfloat vec_ndist ( struct Vect v, struct Vect v1, struct Vect v2 )/* normal distance of v to line(v1,v2) */{    return( vec_abs(vec_ncomp(vec_diff(v,v1),vec_diff(v2,v1))) );}struct Vect vec_surf_proj( struct Vect center, struct Vect point, struct Vect n, struct Vect npos ){    double ndist_c, ndist_p;    npos = vec_proj(npos,n);    ndist_c=vec_mul(center,n)-vec_mul(npos,n);    ndist_p=vec_mul(point,n)-vec_mul(npos,n);    center = vec_ncomp(center,n);    point = vec_ncomp(point,n);    return vec_add( npos,                    vec_add( center,                             vec_scale(vec_diff(point,center),ndist_c/(ndist_c-ndist_p))                           )                    );}struct Vect matr4_rdot( struct Matrix4 m, struct Vect v ){    struct Vect rvec;    rvec.x=v.x*m.m[0]+v.y*m.m[4]+v.z*m.m[ 8]+m.m[12];    rvec.y=v.x*m.m[1]+v.y*m.m[5]+v.z*m.m[ 9]+m.m[13];    rvec.z=v.x*m.m[2]+v.y*m.m[6]+v.z*m.m[10]+m.m[14];    return rvec;}struct Matrix4 matr4_mul(struct Matrix4 m1, struct Matrix4 m2){/*    m1   m5   m      m2   m6      m3   m7      ...  ...      */    int i,j,k;    struct Matrix4 m;    for(i=0;i<4;i++){        for(j=0;j<4;j++){            m.m[i*4+j]=0.0;            for(k=0;k<4;k++){                m.m[i*4+j] += m1.m[i*4+k] + m2.m[k*4+j];            }        }    }    return m;}VMfloat shape_area( struct Shape sh ){    int i,in;    VMfloat a;    a=0.0;    for(i=0;i<sh.pnr;i++){        in=(i+1)%sh.pnr;        a += (sh.p[i].x-sh.p[in].x)*(sh.p[in].y+sh.p[i].y)/2.0;    }    return a;}struct Vect tri_center( struct Vect v1, struct Vect v2, struct Vect v3 ){    return( vec_xyz( (v1.x+v2.x+v3.x)/3.0,                     (v1.y+v2.y+v3.y)/3.0,                     (v1.z+v2.z+v3.z)/3.0 ) );}VMfloat tri_area_xy( struct Vect v1, struct Vect v2, struct Vect v3 )/* area of triangle ( +/- for ccw/cw ) */{    return( ( (v1.x-v2.x)*(v1.y+v2.y) +              (v2.x-v3.x)*(v2.y+v3.y) +              (v3.x-v1.x)*(v3.y+v1.y) ) / 2.0 );}VMfloat tri_vol_xy( struct Vect v1, struct Vect v2, struct Vect v3 )/* calc the volume of the space under (-z) the triangle (v1,v2,v3) */{    return( tri_center(v1,v2,v3).z * tri_area_xy(v1,v2,v3) );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -