Biomechanical Joint Model
 Author: Anderson Maciel

primitive.cpp

Go to the documentation of this file.
00001 /*@#---------------------------------------------------------------------------
00002  PROJECT            : PHD THESIS
00003  MODULE             : PHYSICALLY-BASED DEFORMATION
00004 
00005  FILE               : primitive.C
00006  CREATION DATE      : Tue May  9 10:10:40 MDT 2000
00007  CREATION AUTHOR(S) : aubel 
00008  ------------------------------------------------------------------------------
00009  KEYWORD(S)         : marching cubes, voxelisation, volume
00010  DEFINED TYPE(S)    : 
00011  RELATED TYPE(S)    : 
00012 
00013  FUNCTIONALITY      : 
00014  ------------------------------------------------------------------------------
00015  LANGAGE            : Ansi C++
00016  SYSTEM             : UNIX V 6.x / SGI
00017  GRAPHIC LIBRARY    : SGI  
00018  ------------------------------------------------------------------------------
00019  PROJECT DIRECTOR   : D. THALMANN
00020  LAB                : EPFL- LIG
00021  --------------------------------------------------------------------------#@*/
00022 #include "primitive.h"
00023 #include <stdio.h>
00024 
00025 //namespace MarchingCubes{  
00026  
00027 bool
00028 ImplicitPrimitive::intersectedBy(Ray &ray) const
00029 {
00030    assert(ray.segment == true); // intersection w.r.t. infinite ray not implemented yet 
00031 
00032    fprintf(stderr,"ImplicitPrimitive::intersectedBy\n");
00033    REAL val_ref = getDistance(ray.O);
00034    if (val_ref < 0)
00035    {      
00036       VEC P(3), Pprev(3);
00037       REAL ini = 1E-4;
00038       REAL step = ini;
00039       int j=0;
00040 
00041       for (REAL i=1; step < 0.9; i+=0.1, j++)
00042       {
00043         P = ray.O + step*ray.D;
00044         REAL val = getDistance(P);
00045 #if 0
00046         printf("P=[%lf,%lf,%lf]->%lf, ray.O=[%lf,%lf,%lf]->%lf, step*ray.D=[%lf,%lf,%lf]\n",P[0],P[1],P[2],\
00047                val, ray.O[0],ray.O[1],ray.O[2], val_ref, step*ray.D[0],step*ray.D[1],step*ray.D[2]);
00048         getchar();
00049 #endif
00050 
00051          if (val >= -epsilon)
00052          {
00053            //ray.P = dichotomy(ray.O, P, val_ref, val);
00054            ray.P = dichotomy(Pprev, P, val_ref, val);
00055            ray.t = VEC(ray.P-ray.O).norm() / ray.D.norm();
00056            return true;
00057          }
00058          
00059          step = pow(ini, 1/i);
00060          Pprev=P; val_ref=val;
00061 //       cout << step<< " ";
00062 //       if (j%16==0) cout << endl;
00063       }
00064    }
00065    return false;
00066 }
00067 
00068 REAL 
00069 ImplicitPrimitive::getDistance(const VEC &X) const 
00070 { 
00071    REAL dist = (!bbox.isEmpty() && bbox.contains(X))? density(X)-iso_value : -iso_value;
00072 //   cout << "distance = " << dist << endl;
00073 
00074    return (!bbox.isEmpty() && bbox.contains(X))? density(X)-iso_value : -iso_value; 
00075 }
00076 
00077 // return point at iso-surface between P1 and P2
00078 // if no such point exists, return a 0-length vector
00079 /*
00080 VEC ImplicitPrimitive::dichotomy(const VEC &P1, const VEC &P2, REAL valp1, REAL valp2) const
00081 {
00082 #if 0
00083    printf("dichotomy:P1[%lf,%lf,%lf]<->P2[%lf,%lf,%lf], valp1=%lf, valp2=%lf\n",P1[0],P1[1],P1[2],P2[0],P2[1],P2[2],valp1,valp2);
00084    getchar();
00085 #endif
00086    if (abs(valp1) < epsilon) return P1;   
00087    if (abs(valp2) < epsilon) return P2;   
00088 
00089    VEC P = P1 + 0.5*(P2-P1);
00090    if (abs(valp1-valp2) < epsilon*10e3) return P;
00091 
00092    REAL val = density(P) - iso_value;
00093    if (valp1*val < 0) return dichotomy(P1, P, valp1, val);
00094    if (valp2*val < 0) return dichotomy(P, P2, val, valp2);
00095    
00096    return VEC();
00097 }
00098 */
00099 
00100 
00101 VEC ImplicitPrimitive::dichotomy(const VEC &P1, const VEC &P2, REAL valp1, REAL valp2) const{
00102 
00103   VEC P(3), Pt1=P1, Pt2=P2;
00104   REAL val;
00105   const double EPS = 10e-5;
00106 
00107   while(fabs(valp1-valp2)>EPS){
00108     P=Pt1+0.5*(Pt2-Pt1);
00109     val=density(P)-iso_value;
00110     if(val<0.0){
00111       Pt2=P;
00112       valp2=val;
00113     }
00114     else{
00115       valp1=val;
00116       Pt1=P;
00117     }
00118   }
00119   return P;
00120 
00121 }
00122 
00123 
00124 
00125 void ImplicitPrimitive::findIntersection(const VEC &P1, const VEC &P2, REAL valp1, REAL valp2, 
00126                                     VEC &P, VEC &N) const
00127 {
00128    //   Linearly interpolate the position where an isosurface cuts
00129    //   an edge between P1 and P2, each with their own scalar value
00130    if (fabs(valp1) < epsilon) P = P1;
00131    else if (fabs(valp2) < epsilon) P = P2;
00132    else if (fabs(valp1-valp2) < epsilon) P = P1;
00133    else 
00134    {
00135       REAL mu = fabs(valp1 / (valp2 - valp1));
00136       P[0] = P1[0] + mu*(P2[0]-P1[0]);
00137       P[1] = P1[1] + mu*(P2[1]-P1[1]);
00138       P[2] = P1[2] + mu*(P2[2]-P1[2]);
00139    }
00140 
00141    N = getNormal(P);
00142    N.normalize();
00143 }
00144 //}

Generated on Thu Dec 1 10:13:39 2005 for COME - Biomechanical Joint Model by  doxygen 1.4.5