00001
00016 #include <sstream>
00017 #include <dlrCommon/exception.h>
00018 #include <dlrCommon/types.h>
00019 #include <dlrGeometry/utilities3D.h>
00020 #include <dlrLinearAlgebra/linearAlgebra.h>
00021 #include <dlrNumeric/array2D.h>
00022
00023 namespace dlr {
00024
00025 namespace geometry {
00026
00027
00028 bool
00029 checkIntersect(const Ray3D& ray, const Triangle3D& triangle)
00030 {
00031 double dummy0;
00032 Vector3D dummy1;
00033 return checkIntersect(ray, triangle, dummy1, dummy0);
00034 }
00035
00036
00037 bool
00038 checkIntersect(const Ray3D& ray, const Triangle3D& triangle,
00039 numeric::Vector3D& intersect)
00040 {
00041 double dummy;
00042 return checkIntersect(ray, triangle, intersect, dummy);
00043 }
00044
00045
00046 bool
00047 checkIntersect(const Ray3D& ray, const Triangle3D& triangle,
00048 double& lambda)
00049 {
00050 Vector3D dummy;
00051 return checkIntersect(ray, triangle, dummy, lambda);
00052 }
00053
00054
00055 bool
00056 checkIntersect(const Ray3D& ray, const Triangle3D& triangle,
00057 numeric::Vector3D& intersect, double& lambda)
00058 {
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 Float64 bufferA[9];
00078 Float64 bufferB[3];
00079
00080 Array2D<Float64> AMatrix(3, 3, bufferA);
00081 Array1D<Float64> bVector(3, bufferB);
00082
00083 Vector3D e_0 = triangle.getVertex1() - triangle.getVertex0();
00084 Vector3D e_1 = triangle.getVertex2() - triangle.getVertex0();
00085
00086 AMatrix[0] = e_0.x();
00087 AMatrix[3] = e_0.y();
00088 AMatrix[6] = e_0.z();
00089 AMatrix[1] = e_1.x();
00090 AMatrix[4] = e_1.y();
00091 AMatrix[7] = e_1.z();
00092 AMatrix[2] = -ray.getDirectionVector().x();
00093 AMatrix[5] = -ray.getDirectionVector().y();
00094 AMatrix[8] = -ray.getDirectionVector().z();
00095
00096 bVector[0] = ray.getOrigin().x() - triangle.getVertex0().x();
00097 bVector[1] = ray.getOrigin().y() - triangle.getVertex0().y();
00098 bVector[2] = ray.getOrigin().z() - triangle.getVertex0().z();
00099
00100 try {
00101 linearSolveInPlace(AMatrix, bVector);
00102 } catch(const ValueException&) {
00103
00104
00105 return false;
00106 }
00107
00108 if(bVector[0] < 0.0 || bVector[1] < 0.0) {
00109
00110
00111 return false;
00112 }
00113
00114
00115
00116
00117
00118
00119 Vector3D intersectionPoint =
00120 ray.getOrigin() + bVector[2] * ray.getDirectionVector();
00121 Vector3D offsetFromVertex1 = triangle.getVertex1() - intersectionPoint;
00122 Vector3D e_2 = triangle.getVertex2() - triangle.getVertex1();
00123
00124 Vector3D crossProduct0 = cross(offsetFromVertex1, -e_0);
00125 Vector3D crossProduct1 = cross(offsetFromVertex1, e_2);
00126 double dotProduct = dot(crossProduct0, crossProduct1);
00127
00128 if(dotProduct >= 0.0) {
00129 return false;
00130 }
00131
00132 lambda = bVector[2];
00133 intersect = intersectionPoint;
00134 return true;
00135 }
00136
00137
00138 Vector3D
00139 findIntersect(const Ray3D& ray, const Plane3D& plane)
00140 {
00141 double dummy;
00142 return findIntersect(ray, plane, dummy);
00143 }
00144
00145
00146 Vector3D
00147 findIntersect(const Ray3D& ray, const Plane3D& plane, double& distance)
00148 {
00149 Float64 bufferA[9];
00150 Float64 bufferB[3];
00151
00152 Array2D<double> AMatrix(3, 3, bufferA);
00153 Array1D<double> bVector(3, bufferB);
00154
00155 AMatrix[0] = ray.getDirectionVector().x();
00156 AMatrix[3] = ray.getDirectionVector().y();
00157 AMatrix[6] = ray.getDirectionVector().z();
00158 AMatrix[1] = plane.getDirectionVector0().x();
00159 AMatrix[4] = plane.getDirectionVector0().y();
00160 AMatrix[7] = plane.getDirectionVector0().z();
00161 AMatrix[2] = plane.getDirectionVector1().x();
00162 AMatrix[5] = plane.getDirectionVector1().y();
00163 AMatrix[8] = plane.getDirectionVector1().z();
00164
00165 bVector[0] = plane.getOrigin().x() - ray.getOrigin().x();
00166 bVector[1] = plane.getOrigin().y() - ray.getOrigin().y();
00167 bVector[2] = plane.getOrigin().z() - ray.getOrigin().z();
00168
00169 try {
00170 linearSolveInPlace(AMatrix, bVector);
00171 } catch(const ValueException&) {
00172 std::ostringstream message;
00173 message << "Unable to find intersection of " << ray << " with "
00174 << plane << ". Perhaps the ray is parallel to the plane.";
00175 DLR_THROW(ValueException, "findIntersect()", message.str().c_str());
00176 }
00177
00178 distance = bVector[0];
00179 return ray.getOrigin() + distance * ray.getDirectionVector();
00180 }
00181
00182
00183 numeric::Vector3D
00184 findIntersect(const Ray3D& ray0, const Ray3D& ray1,
00185 double& distance0, double& distance1, double& residual)
00186 {
00187 Array2D<double> AMatrix(3, 2);
00188 AMatrix(0, 0) = ray0.getDirectionVector().x();
00189 AMatrix(1, 0) = ray0.getDirectionVector().y();
00190 AMatrix(2, 0) = ray0.getDirectionVector().z();
00191 AMatrix(0, 1) = -ray1.getDirectionVector().x();
00192 AMatrix(1, 1) = -ray1.getDirectionVector().y();
00193 AMatrix(2, 1) = -ray1.getDirectionVector().z();
00194
00195 Array1D<double> bVector(3);
00196 bVector[0] = ray1.getOrigin().x() - ray0.getOrigin().x();
00197 bVector[1] = ray1.getOrigin().y() - ray0.getOrigin().y();
00198 bVector[2] = ray1.getOrigin().z() - ray0.getOrigin().z();
00199
00200 Array2D<double> APinv;
00201 try {
00202 APinv = linearAlgebra::pseudoinverse(AMatrix);
00203 } catch(ValueException const&) {
00204 DLR_THROW(ValueException, "findIntersect()",
00205 "Trouble inverting matrix. "
00206 "Input rays must not be parallel. ");
00207 }
00208 Array1D<double> parameters = matrixMultiply(APinv, bVector);
00209
00210 distance0 = parameters[0];
00211 distance1 = parameters[1];
00212 Vector3D point0 =
00213 ray0.getOrigin() + distance0 * ray0.getDirectionVector();
00214 Vector3D point1 =
00215 ray1.getOrigin() + distance1 * ray1.getDirectionVector();
00216 residual = magnitude(point1 - point0) / 2.0;
00217 return 0.5 * (point0 + point1);
00218 }
00219
00220
00221 Plane3D
00222 operator*(const numeric::Transform3D& transform,
00223 const Plane3D& inputPlane)
00224 {
00225 Vector3D newOrigin = transform * inputPlane.getOrigin();
00226 Vector3D newEndPoint0 =
00227 transform * (inputPlane.getOrigin() + inputPlane.getDirectionVector0());
00228 Vector3D newEndPoint1 =
00229 transform * (inputPlane.getOrigin() + inputPlane.getDirectionVector1());
00230 return Plane3D(newOrigin, newEndPoint0, newEndPoint1);
00231 }
00232
00233
00234 Ray3D
00235 operator*(const numeric::Transform3D& transform,
00236 const Ray3D& inputRay)
00237 {
00238 Vector3D newOrigin = transform * inputRay.getOrigin();
00239 Vector3D newEndpoint =
00240 transform * (inputRay.getOrigin() + inputRay.getDirectionVector());
00241 return Ray3D(newOrigin, newEndpoint - newOrigin, false);
00242 }
00243
00244
00245 Triangle3D
00246 operator*(const numeric::Transform3D& transform,
00247 const Triangle3D& inputTriangle)
00248 {
00249 Vector3D newVertex0 = transform * inputTriangle.getVertex0();
00250 Vector3D newVertex1 = transform * inputTriangle.getVertex1();
00251 Vector3D newVertex2 = transform * inputTriangle.getVertex2();
00252 return Triangle3D(newVertex0, newVertex1, newVertex2);
00253 }
00254
00255
00256 }
00257
00258 }