00001
00002 #include <Triangle.h>
00003
00004
00005 Triangle::Triangle(){}
00006 Triangle::Triangle(const V_3D& x0,const V_3D& x1,const V_3D& x2)
00007 {x[0]=x0;x[1]=x1;x[2]=x2;}
00008 Triangle::Triangle(const Triangle& t)
00009 {for(int k_dim=0;k_dim<3;k_dim++){x[k_dim]=t.x[k_dim];}}
00010 Triangle::~Triangle(){destroy();}
00011
00012 int Triangle::destroy(){for(int k_dim=0;k_dim<3;k_dim++)x[k_dim].set(0.0,0.0,0.0);return 0;}
00013
00014 V_3D Triangle::operator()(int index) const
00015 {
00016 if(index<0 || index>2){printf("Error in operator(%d) in Triangle, index must be in [0,3]\n",index);exit(-1);}
00017 return x[index];
00018 }
00019 V_3D& Triangle::operator()(int index)
00020 {
00021 if(index<0 || index>2){printf("Error in operator(%d) in Triangle, index must be in [0,3]\n",index);exit(-1);}
00022 return x[index];
00023 }
00024 V_3D Triangle::operator[](int index) const
00025 {
00026 if(index<0 || index>2){printf("Error in operator[%d] in Triangle, index must be in [0,3]\n",index);exit(-1);}
00027 return x[index];
00028 }
00029 V_3D Triangle::operator[](int index)
00030 {
00031 if(index<0 || index>2){printf("Error in operator[%d] in Triangle, index must be in [0,3]\n",index);exit(-1);}
00032 return x[index];
00033 }
00034 Triangle& Triangle::operator=(const Triangle& t)
00035 {for(int k_dim=0;k_dim<3;k_dim++){x[k_dim]=t.x[k_dim];} return *this;}
00036
00037
00038 int Triangle::barycentric_coordinates(const V_3D& _x,double *alpha,double *beta,double *gamma) const
00039 {
00040
00041 double epsilon=0.0001;
00042 double L = (_x-x[0]).dot(normal());
00043 if(L>epsilon)
00044 return -1;
00045
00046
00047
00048
00049 double area_1=0.0,area_2=0.0,area_3=0.0,area_tot=0.0;
00050 area_1 = (x[1]-x[0]).area(_x-x[0]);
00051 area_2 = (x[2]-x[1]).area(_x-x[1]);
00052 area_3 = (x[0]-x[2]).area(_x-x[2]);
00053 area_tot = area();
00054
00055 *alpha = area_1/area_tot;
00056 *beta = area_2/area_tot;
00057 *gamma = area_3/area_tot;
00058
00059 return 0;
00060 }
00061
00062 int Triangle::is_vertex_inside(const V_3D _x) const
00063 {
00064 double alpha=-1.0,beta=-1.0,gamma=-1.0;
00065 if(barycentric_coordinates(_x,&alpha,&beta,&gamma)==-1)
00066 return 0;
00067
00068 double epsilon=0.0001;
00069 if(alpha>1.0 || beta>1.0 || gamma>1.0 || (alpha+beta+gamma-1.0)>epsilon)
00070 return 0;
00071
00072
00073 return 1;
00074 }
00075
00076 V_3D Triangle::normal() const
00077 {return (x[2]-x[0]).vector_prod(x[1]-x[0]).normalized();}
00078
00079 double Triangle::area() const
00080 {return (x[2]-x[0]).area(x[1]-x[0]);}
00081
00082 V_3D Triangle::closest_point(const V_3D& _x,int *type) const
00083 {
00084 double epsilon=0.00001;
00085
00086
00087 V_3D n=normal();
00088 V_3D proj = _x-((_x-x[0]).dot(n))*n;
00089
00090
00091 if(is_vertex_inside(proj)==1)
00092 {*type=0;return proj;}
00093
00094
00095
00096 *type=1;
00097 Segment s0=get_segment(0),s1=get_segment(1),s2=get_segment(2);
00098 V_3D y0=s0.closest_point(_x),y1=s1.closest_point(_x),y2=s2.closest_point(_x);
00099 double dist_1=(y0-_x).norm(),dist_2=(y1-_x).norm(),dist_3=(y2-_x).norm();
00100 if(dist_1<=dist_2 && dist_1<=dist_3)
00101 {
00102
00103 for(int k=0;k<3;k++){if((y0-x[k]).norm()<epsilon) *type=2;}
00104 return y0;
00105 }
00106 else if(dist_2<=dist_1 && dist_2<=dist_3)
00107 {
00108 for(int k=0;k<3;k++){if((y1-x[k]).norm()<epsilon) *type=2;}
00109 return y1;
00110 }
00111 else
00112 {
00113 for(int k=0;k<3;k++){if((y2-x[k]).norm()<epsilon) *type=2;}
00114 return y2;
00115 }
00116
00117 }
00118
00119 Segment Triangle::get_segment(int k_edge) const
00120 {
00121 if(k_edge<0 || k_edge>2)
00122 {printf("Error in get_segment(%d) in Triangle, k_edge has to be between 0 and 2\n",k_edge);exit(-1);}
00123
00124 Segment s(x[k_edge],x[(k_edge+1)%3]);
00125 return s;
00126 }
00127
00128 std::vector <V_3D> Triangle::plane_intersection(const V_3D& n,const V_3D& x0,int *type) const
00129 {int type_0=1,type_1=-1,type_2=1;return plane_intersection(n,x0,type,&type_0,&type_1,&type_2);}
00130 std::vector <V_3D> Triangle::plane_intersection(const V_3D& n,const V_3D& x0,int *type,int *type_0,int *type_1,int *type_2) const
00131 {
00132 Segment s0=get_segment(0),s1=get_segment(1),s2=get_segment(2);
00133 *type_0=-1,*type_1=-1,*type_2=-1;
00134 V_3D inter_0(-1.0,-1.0,-1.0),inter_1(-1.0,-1.0,-1.0),inter_2(-1.0,-1.0,-1.0);
00135
00136
00137 inter_0=s0.plane_intersection(n,x0,type_0);
00138 inter_1=s1.plane_intersection(n,x0,type_1);
00139 inter_2=s2.plane_intersection(n,x0,type_2);
00140
00141 std::vector <V_3D> intersections;
00142
00143
00144 if(*type_0==0 && *type_1==0 && *type_2==0)
00145 {*type=0;return intersections;}
00146
00147
00148
00149 if(*type_0==3){*type=3;intersections.push_back(x[0]),intersections.push_back(x[1]);return intersections;}
00150 if(*type_1==3){*type=3;intersections.push_back(x[1]),intersections.push_back(x[2]);return intersections;}
00151 if(*type_2==3){*type=3;intersections.push_back(x[2]),intersections.push_back(x[0]);return intersections;}
00152
00153
00154 if(*type_0==2 && *type_1!=1 && *type_2!=1){*type=2;intersections.push_back(x[0]);return intersections;}
00155 if(*type_1==2 && *type_0!=1 && *type_2!=1){*type=2;intersections.push_back(x[1]);return intersections;}
00156 if(*type_2==2 && *type_0!=1 && *type_1!=1){*type=2;intersections.push_back(x[2]);return intersections;}
00157
00158
00159 if( (*type_0==1 || *type_0==2) && (*type_1==1 || *type_1==2) )
00160 {*type=1;intersections.push_back(inter_0);intersections.push_back(inter_1);return intersections;}
00161 if( (*type_0==1 || *type_0==2) && (*type_2==1 || *type_2==2) )
00162 {*type=1;intersections.push_back(inter_0);intersections.push_back(inter_2);return intersections;}
00163 if( (*type_1==1 || *type_1==2) && (*type_2==1 || *type_2==2) )
00164 {*type=1;intersections.push_back(inter_1);intersections.push_back(inter_2);return intersections;}
00165
00166
00167
00168 cout<<"Error in plane_intersection("<<n<<","<<x0<<") ";
00169 printf("Unknown configuration type=(%d,%d,%d)\n",*type_0,*type_1,*type_2);
00170 exit(-1);
00171 }