00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Geometry/Distance/SegmentDistance.h"
00027
00028 namespace Lamp{
00029
00030
00031
00032
00033
00034 float SegmentDistance::squaredDistance(
00035 const Segment& segment, const Vector3& point){
00036 const Vector3& direction = segment.getDirection();
00037 Vector3 distance = point - segment.getOrigin();
00038 float t = distance.dotProduct(direction);
00039
00040 if(t > 0.f){
00041 float squaredLength = direction.getSquaredLength();
00042 if(t >= squaredLength){
00043
00044
00045 distance -= direction;
00046 }else{
00047 t /= squaredLength;
00048 distance -= t * direction;
00049 }
00050 }
00051 return distance.getSquaredLength();
00052 }
00053
00054
00055
00056
00057 float SegmentDistance::squaredDistance(
00058 const Segment& segment0, const Segment& segment1){
00059 const Vector3& origin0 = segment0.getOrigin();
00060 const Vector3& direction0 = segment0.getDirection();
00061 const Vector3& origin1 = segment1.getOrigin();
00062 const Vector3& direction1 = segment1.getDirection();
00063 Vector3 direction2 = origin0 - origin1;
00064 float dot00 = direction0.dotProduct(direction0);
00065 float dot01 = direction0.dotProduct(direction1);
00066 float dot11 = direction1.dotProduct(direction1);
00067 float dot02 = direction0.dotProduct(direction2);
00068 float dot12 = direction1.dotProduct(direction2);
00069 float determ = dot00 * dot11 - dot01 * dot01;
00070 float sValue, tValue, sDenom, tDenom;
00071 sDenom = tDenom = determ;
00072
00073
00074 if(determ <= Math::epsilon){
00075 sValue = 0.f;
00076 sDenom = 1.f;
00077 tValue = dot12;
00078 tDenom = dot11;
00079 }else{
00080 sValue = dot01 * dot12 - dot11 * dot02;
00081 tValue = dot00 * dot12 - dot01 * dot02;
00082 }
00083
00084
00085 if(sValue < 0.f){
00086 sValue = 0.f;
00087 tValue = dot12;
00088 tDenom = dot11;
00089 }else if(sValue > determ){
00090 sValue = determ;
00091 tValue = dot01 + dot12;
00092 tDenom = dot11;
00093 }
00094
00095
00096 if(tValue < 0.f){
00097 tValue = 0.f;
00098 float tmpS = (-dot02);
00099 if(tmpS < 0.f){
00100 sValue = 0.f;
00101 }else if(tmpS > dot00){
00102 sValue = sDenom;
00103 }else{
00104 sValue = tmpS;
00105 sDenom = dot00;
00106 }
00107 }else if(tValue > tDenom){
00108 tValue = tDenom;
00109 float tmpS = dot01 - dot02;
00110 if(tmpS < 0.f){
00111 sValue = 0.f;
00112 }else if(tmpS > dot00){
00113 sValue = sDenom;
00114 }else{
00115 sValue = tmpS;
00116 sDenom = dot00;
00117 }
00118 }
00119
00120 float s, t;
00121 if(Math::abs(sDenom) > Math::epsilon){ s = sValue / sDenom; }
00122 else{ s = 0.f; }
00123 if(Math::abs(tDenom) > Math::epsilon){ t = tValue / tDenom; }
00124 else{ t = 0.f; }
00125
00126 Vector3 direction =
00127 (origin0 + (s * direction0)) - (origin1 + (t * direction1));
00128 return direction.getSquaredLength();
00129 }
00130
00131
00132
00133
00134 float SegmentDistance::squaredDistance(
00135 const Segment& segment, const Sphere& sphere){
00136 Assert(false);
00137 return 0.f;
00138 }
00139
00140
00141
00142
00143 float SegmentDistance::squaredDistance(
00144 const Segment& segment, const Triangle& triangle){
00145 Assert(false);
00146 return 0.f;
00147 }
00148
00149 }
00150