00001
00002
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;
00027 char rigidity;
00028 int force;
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
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