/Users/craigcornelius/Projects/SPRING Mac Release 0.2/triangles.h

Go to the documentation of this file.
00001 // $Id: triangles.h,v 1.18 2002/01/02 01:40:46 kevin Exp $
00002 // $Copyright: (c)2001 National Biocomputation Center, Stanford University $
00003 
00004 #ifndef _TRIANGLES_H_
00005 #define _TRIANGLES_H_
00006 
00007 #include <stdio.h>
00008 
00009 #include "point3d.h"
00010 #include "reallocablearray.h"
00011 #include "space.h"
00012 #include "socket.h"
00013 
00014 #define COEFF 0.5
00015 #define WIDTH 1.0
00016 
00017 class triangle {
00018 public :
00019     Point3D p1;
00020     Point3D p2;
00021     Point3D p3;
00022     Point3D t1;
00023     Point3D t2;
00024     Point3D t3;
00025     Point3D normal;
00026     double d;   // The 4th useful parameters for the equation of the plane.
00027     char rigidity;
00028     int force;   // This is true if I had a force last time I ask for getForce.
00029     
00030     triangle(const Point3D& np1, const Point3D& np2,
00031         const Point3D& np3, const Point3D& nt1,
00032         const Point3D& nt2, const Point3D& nt3,
00033         char nrigidity) : p1(np1), p2(np2), p3(np3), t1(nt1), t2(nt2), t3(nt3)
00034            {
00035         force = 0;
00036         Point3D u = p2 - p1, v = p3 - p1;
00037         
00038         rigidity = nrigidity;
00039         normal = Point3D(u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x);
00040         normal /= sqrt(normal.Squared());
00041         d = - (normal.x * p1.x + normal.y * p1.y + normal.z * p1.z);
00042         if(t1.Dot(normal) < 0)
00043             t1 = -t1;
00044         if(t2.Dot(normal) < 0)
00045             t2 = -t2;
00046         if(t3.Dot(normal) < 0)
00047             t3 = -t3;
00048            }
00049     triangle() : p1(), p2(), p3(), t1(), t2(), t3(), normal()
00050     {
00051         force = 0;
00052         rigidity = 0;
00053         d = 0;
00054     }
00055     ~triangle()
00056     {
00057     }
00058     
00059     long gethash()
00060     {
00061         long res;
00062         
00063         res = hashdouble(p1.x); res ^= hashdouble(p1.y); res ^= hashdouble(p1.z);
00064         res ^= hashdouble(p2.x); res ^= hashdouble(p2.y); res ^= hashdouble(p2.z);
00065         res ^= hashdouble(p3.x); res ^= hashdouble(p3.y); res ^= hashdouble(p3.z);
00066         res ^= hashdouble(t1.x); res ^= hashdouble(t1.y); res ^= hashdouble(t1.z);
00067         res ^= hashdouble(t2.x); res ^= hashdouble(t2.y); res ^= hashdouble(t2.z);
00068         res ^= hashdouble(t3.x); res ^= hashdouble(t3.y); res ^= hashdouble(t3.z);
00069         return res;
00070     }
00071     
00072     Point3D *get_force(Point3D *pos, Point3D *res)
00073     {
00074         int test[3];
00075         Point3D proj;
00076         double d1,d2,d3;
00077         double l;
00078         double sign;
00079         
00080         if(res == NULL)
00081             res = new Point3D();
00082         
00083         l = ((normal.Dot(*pos) + d) / normal.Squared());
00084         
00085         if(l<0)
00086         {
00087             sign = -1;
00088             l = -l;
00089         }
00090         else
00091             sign = 1;
00092         
00093         if(l >= WIDTH)
00094         {
00095             force = 0;
00096             *res = Point3D(0,0,0);
00097             return res;
00098         }
00099         else
00100         {
00101             //   cerr << fabs(l) << endl;
00102         }  
00103         
00104         proj = *pos - sign * l * normal;
00105         
00106         test[0] = ((p2 - p1).Cross(proj - p1).Dot(normal) > 0?1:-1);
00107         test[1] = ((p3 - p2).Cross(proj - p2).Dot(normal) > 0?1:-1);
00108         test[2] = ((p1 - p3).Cross(proj - p3).Dot(normal) > 0?1:-1);
00109         
00110         if(test[0] == 0)
00111             *res = Point3D(t1);
00112         else if(test[1] == 0)
00113             *res = Point3D(t2);
00114         else if(test[2] == 0)
00115             *res = Point3D(t3);
00116         else if((test[0] == test[1]) && (test[1] == test[2]))
00117         {
00118             d1 = sqrt((proj - p1).Squared());
00119             d2 = sqrt((proj - p2).Squared());
00120             d3 = sqrt((proj - p3).Squared());
00121             *res = Point3D(((1.0/d1) * t1) + ((1.0/d2) * t2) + ((1.0/d3) * t3));
00122             *res *= 1.0 / ((1.0/d1) + (1.0/d2) + (1.0/d3));
00123         }
00124         else
00125         {
00126             *res = Point3D(0,0,0);
00127             force = 0;
00128             return res;
00129         }
00130         force = 1;
00131         *res *= (1.0 - pow((l/WIDTH), 2.0)) * rigidity * COEFF;
00132         cerr << "There is a force of magnitude: " << res->Squared() << "." << endl;
00133         return res;
00134     }
00135     
00136     void print_datas()
00137     {
00138     fprintf(stderr, "Triangle class.\nRigidity: %d\np1: %f,%f,%f\nt1: %f,%f,%f\n\
00139                                                                                   p2: %f,%f,%f\nt2: %f,%f,%f\n\
00140 p3: %f,%f,%f\nt3: %f,%f,%f\n",
00141 rigidity,p1.x,p1.y,p1.z,t1.x,t1.y,t1.z,
00142 p2.x,p2.y,p2.z,t2.x,t2.y,t2.z,
00143 p3.x,p3.y,p3.z,t3.x,t3.y,t3.z);
00144     }
00145     
00146     void receive_data(char *buf)
00147     {
00148         int j;
00149         Point3D u,v;
00150         
00151         j=0;
00152         rigidity = buf[j];
00153         j++;
00154         receive_float_from_buf(buf + j, &(p1.x));
00155         j+=4;
00156         receive_float_from_buf(buf + j, &(p1.y));
00157         j+=4;
00158         receive_float_from_buf(buf + j, &(p1.z));
00159         j+=4;
00160         receive_float_from_buf(buf + j, &(t1.x));
00161         j+=4;
00162         receive_float_from_buf(buf + j, &(t1.y));
00163         j+=4;
00164         receive_float_from_buf(buf + j, &(t1.z));
00165         j+=4;
00166         receive_float_from_buf(buf + j, &(p2.x));
00167         j+=4;
00168         receive_float_from_buf(buf + j, &(p2.y));
00169         j+=4;
00170         receive_float_from_buf(buf + j, &(p2.z));
00171         j+=4;
00172         receive_float_from_buf(buf + j, &(t2.x));
00173         j+=4;
00174         receive_float_from_buf(buf + j, &(t2.y));
00175         j+=4;
00176         receive_float_from_buf(buf + j, &(t2.z));
00177         j+=4;
00178         receive_float_from_buf(buf + j, &(p3.x));
00179         j+=4;
00180         receive_float_from_buf(buf + j, &(p3.y));
00181         j+=4;
00182         receive_float_from_buf(buf + j, &(p3.z));
00183         j+=4;
00184         receive_float_from_buf(buf + j, &(t3.x));
00185         j+=4;
00186         receive_float_from_buf(buf + j, &(t3.y));
00187         j+=4;
00188         receive_float_from_buf(buf + j, &(t3.z));
00189         u = p2 - p1;
00190         v = p3 - p1;
00191         normal = Point3D(u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x);
00192         normal /= sqrt(normal.Squared());
00193         d = - (normal.x * p1.x + normal.y * p1.y + normal.z * p1.z);
00194         if(t1.Dot(normal) < 0)
00195             t1 = -t1;
00196         if(t2.Dot(normal) < 0)
00197             t2 = -t2;
00198         if(t3.Dot(normal) < 0)
00199             t3 = -t3;
00200     }
00201     
00202     void data_to_send(char *buf)
00203     {
00204         int j;
00205         
00206         j = 0;
00207         buf[j] = rigidity;
00208         j++;
00209         copy_float_to_buf(buf + j, p1.x);
00210         j+=4;
00211         copy_float_to_buf(buf + j, p1.y);
00212         j+=4;
00213         copy_float_to_buf(buf + j, p1.z);
00214         j+=4;
00215         copy_float_to_buf(buf + j, t1.x);
00216         j+=4;
00217         copy_float_to_buf(buf + j, t1.y);
00218         j+=4;
00219         copy_float_to_buf(buf + j, t1.z);
00220         j+=4;
00221         copy_float_to_buf(buf + j, p2.x);
00222         j+=4;
00223         copy_float_to_buf(buf + j, p2.y);
00224         j+=4;
00225         copy_float_to_buf(buf + j, p2.z);
00226         j+=4;
00227         copy_float_to_buf(buf + j, t2.x);
00228         j+=4;
00229         copy_float_to_buf(buf + j, t2.y);
00230         j+=4;
00231         copy_float_to_buf(buf + j, t2.z);
00232         j+=4;
00233         copy_float_to_buf(buf + j, p3.x);
00234         j+=4;
00235         copy_float_to_buf(buf + j, p3.y);
00236         j+=4;
00237         copy_float_to_buf(buf + j, p3.z);
00238         j+=4;
00239         copy_float_to_buf(buf + j, t3.x);
00240         j+=4;
00241         copy_float_to_buf(buf + j, t3.y);
00242         j+=4;
00243         copy_float_to_buf(buf + j, t3.z);
00244     }
00245     
00246 };
00247 
00248 typedef ReallocableArray<triangle *> triangle_l;
00249 
00250 class space_t : public space {
00251 public:
00252     triangle_l my_triangles;
00253     
00254     space_t()
00255     { }
00256     
00257     virtual ~space_t()
00258     { erase_all(); }
00259     
00260     void add_new_triangle(triangle *t)
00261     {
00262         my_triangles.Append(t);
00263     }
00264     
00265     virtual void print_datas()
00266     {
00267         fprintf(stderr, "Space of triangle.\n");
00268                 for (int i=0; i< my_triangles.NumElements(); i++) {
00269                   triangle* cur = my_triangles[i];
00270           cur->print_datas();
00271                 }
00272     }
00273     
00274     virtual void erase_all()
00275     { my_triangles.DeleteAll(); }
00276     
00277     virtual void send_datas(Socket *s)
00278     {
00279         unsigned short size;
00280         int j;
00281         char *buf;
00282         us_t l;
00283         
00284         size = 73 * my_triangles.NumElements();
00285         buf = (char *) malloc(sizeof(char) * (3 + size));
00286         if(buf == NULL)
00287             return;
00288         l.s = htons(size);
00289         buf[0] = TYPE_TRIANGLE;
00290         for(int k=0; k<2; k++)
00291             buf[k+1] = l.c[k];
00292         j=0;
00293                 for (int i=0; i< my_triangles.NumElements(); i++) {
00294                   triangle* cur = my_triangles[i];
00295           (cur)->data_to_send(buf + 3 + (73*j));
00296           j++;
00297         }
00298         s->Send(buf, 3 + size);
00299         free(buf);
00300     }
00301     
00302     virtual void use_new_datas(char *buf, int size)
00303     {
00304         int i,nb;
00305         triangle *t;
00306         
00307         nb = size / 73;
00308         
00309         erase_all();
00310         
00311         for(i=0;i<nb; i++)
00312         {
00313             t = new triangle();
00314             t->receive_data(buf);
00315             add_new_triangle(t);
00316             buf+=73;
00317         }
00318     }
00319     
00320     virtual Point3D *get_force(Point3D *pos, Point3D *res)
00321     {
00322         Point3D tmp;
00323         
00324         if(res == NULL)
00325             res = new Point3D;
00326         
00327         *res = Point3D(0,0,0);
00328         
00329                 for (int i=0; i< my_triangles.NumElements(); i++) {
00330                   triangle* cur = my_triangles[i];
00331           cur->get_force(pos, &tmp);
00332           *res += tmp;
00333         }
00334         
00335         return res;
00336     }
00337     
00338     virtual int istouching()
00339     {
00340                 for (int i=0; i< my_triangles.NumElements(); i++) {
00341                   triangle* cur = my_triangles[i];
00342           if(cur->force)
00343               return 1;
00344         }
00345         return 0;
00346     }
00347     
00348     virtual long gethash()
00349     {
00350         long res = 0;
00351                 for (int i=0; i< my_triangles.NumElements(); i++) {
00352                   triangle* cur = my_triangles[i];
00353           res ^= cur->gethash();
00354         }
00355         
00356         return res;
00357     }
00358     
00359 };
00360 
00361 #endif

Generated on Thu Aug 30 11:03:17 2007 for SPRING Mac by  doxygen 1.5.3