36 #define _BACKWARD_BACKWARD_WARNING_H 1 //Cut out the vtk deprecated warning for now (gcc4.3) 39 #include <vtkPoints.h> 40 #include <vtkSmartPointer.h> 41 #include <vtkUnstructuredGrid.h> 42 #include <vtkCellLocator.h> 43 #include "Exception.hpp" 44 #include "GeometryTools.hpp" 45 #include "UblasVectorInclude.hpp" 46 #include "UblasIncludes.hpp" 47 #include "UblasCustomFunctions.hpp" 49 template<
unsigned DIM>
54 return norm_2(rLocation2.
GetLocation(reference_length) - rLocation1.
GetLocation(reference_length))*reference_length;
57 template<
unsigned DIM>
62 return inner_prod(rLocation2.
GetLocation(reference_length), rLocation1.
GetLocation(reference_length))*reference_length*reference_length;
65 template<
unsigned DIM>
67 const c_vector<double, DIM>& rLocation2)
70 return inner_prod(rLocation2 , rLocation1.
GetLocation(reference_length_1))*reference_length_1;
73 template<
unsigned DIM>
82 units::quantity<unit::area> dp_segment_point = GetDotProduct(segment_vector, point_vector);
83 units::quantity<unit::area> dp_segment_segment = GetDotProduct(segment_vector, segment_vector);
85 if (dp_segment_point <= 0.0*unit::metres*unit::metres || dp_segment_segment <= dp_segment_point)
89 EXCEPTION(
"Projection of point is outside segment.");
93 units::quantity<unit::length> dist1 = (rStartLocation - rEndLocation).GetNorm2();
94 units::quantity<unit::length> dist2 = (rEndLocation - rProbeLocation).GetNorm2();
97 return rStartLocation;
106 return rStartLocation + segment_vector*(dp_segment_point / dp_segment_segment);
109 template<
unsigned DIM>
115 units::quantity<unit::area> dp_segment_point = GetDotProduct(segment_vector, rProbeLocation - rStartLocation);
117 if (dp_segment_point <= 0.0*unit::metres*unit::metres)
119 return rStartLocation.GetDistance(rProbeLocation);
122 units::quantity<unit::area> dp_segment_segment = GetDotProduct(segment_vector, segment_vector);
124 if (dp_segment_segment <= dp_segment_point)
130 double projection_ratio = dp_segment_point / dp_segment_segment;
132 return projected_location.
GetNorm2();
135 template<
unsigned DIM>
137 units::quantity<unit::length> probeLength)
139 unsigned num_probes = (2*DIM)+1;
143 double normalized_probe_length = probeLength/length_scale;
144 probe_locations[0] = rCentrePoint;
145 probe_locations[1] = rCentrePoint +
DimensionalChastePoint<DIM>(normalized_probe_length * unit_vector<double>(DIM,0), length_scale);
146 probe_locations[2] = rCentrePoint +
DimensionalChastePoint<DIM>(normalized_probe_length * unit_vector<double>(DIM,0), length_scale);
147 probe_locations[3] = rCentrePoint +
DimensionalChastePoint<DIM>(normalized_probe_length * unit_vector<double>(DIM,1), length_scale);
148 probe_locations[4] = rCentrePoint +
DimensionalChastePoint<DIM>(normalized_probe_length * unit_vector<double>(DIM,1), length_scale);
151 probe_locations[5] = rCentrePoint +
DimensionalChastePoint<DIM>(normalized_probe_length * unit_vector<double>(DIM,2), length_scale);
152 probe_locations[6] = rCentrePoint +
DimensionalChastePoint<DIM>(normalized_probe_length * unit_vector<double>(DIM,2), length_scale);
154 return probe_locations;
157 template<
unsigned DIM>
161 units::quantity<unit::length> probeLength,
162 units::quantity<unit::plane_angle> angle)
164 unsigned num_probes = 2*DIM - 1;
167 probe_locations[0] = rCentralPoint;
168 double normalized_probe_length = probeLength/length_scale;
172 c_vector<double, DIM> unit_axis = rRotationAxis.
GetUnitVector();
173 c_vector<double, DIM> new_direction = RotateAboutAxis<DIM>(rInitialDirection.
GetUnitVector(), unit_axis, angle);
174 new_direction /= norm_2(new_direction);
177 c_vector<double, DIM> new_direction_r1 = RotateAboutAxis<DIM>(new_direction, unit_axis, M_PI*unit::radians);
178 new_direction_r1 /= norm_2(new_direction_r1);
181 c_vector<double, DIM> new_direction_r2 = RotateAboutAxis<DIM>(new_direction, unit_axis, M_PI/2.0*unit::radians);
182 new_direction_r2 /= norm_2(new_direction_r2);
185 c_vector<double, DIM> new_direction_r3 = RotateAboutAxis<DIM>(new_direction, unit_axis, 3.0*M_PI/2.0*unit::radians);
186 new_direction_r3 /= norm_2(new_direction_r3);
192 probe_locations[1] = rCentralPoint + new_direction;
193 probe_locations[2] = rCentralPoint - new_direction;
196 return probe_locations;
199 template<
unsigned DIM>
207 units::quantity<unit::length> dist_apex_base = apex_to_base.
GetNorm2();
208 units::quantity<unit::area> dp_point_base = GetDotProduct(apex_to_point, apex_to_base);
209 bool in_infinite_cone = dp_point_base / (apex_to_point.
GetNorm2() * dist_apex_base) > std::cos(aperture/2.0);
210 if(!in_infinite_cone)
214 return dp_point_base / dist_apex_base < dist_apex_base;
217 template<
unsigned DIM>
221 bool point_in_box =
false;
223 c_vector<double, DIM> location_in_point_scale = rLocation.
GetLocation(point_length_scale);
224 c_vector<double, DIM> dimensionless_point = rPoint.
GetLocation(point_length_scale);
225 double dimensionless_spacing = spacing/point_length_scale;
227 bool inside_left = dimensionless_point[0] >= location_in_point_scale[0] -dimensionless_spacing/2.0;
228 bool inside_right = dimensionless_point[0] <= location_in_point_scale[0] + dimensionless_spacing/2.0;
229 if(inside_left && inside_right)
231 if(dimensionless_point[1] >= location_in_point_scale[1] -dimensionless_spacing/2.0 && dimensionless_point[1] <=
232 location_in_point_scale[1] + dimensionless_spacing/2.0)
236 if(dimensionless_point[2] >= location_in_point_scale[2] -dimensionless_spacing/2.0 && dimensionless_point[2] <=
237 location_in_point_scale[2] + dimensionless_spacing/2.0)
251 template<
unsigned DIM>
255 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints> :: New();
256 c_vector<double, DIM> loc0 = locations[0].GetLocation(scale_factor);
257 c_vector<double, DIM> loc1 = locations[1].GetLocation(scale_factor);
258 c_vector<double, DIM> loc2 = locations[2].GetLocation(scale_factor);
259 c_vector<double, DIM> loc3 = locations[3].GetLocation(scale_factor);
262 points->InsertNextPoint(&loc0[0]);
263 points->InsertNextPoint(&loc1[0]);
264 points->InsertNextPoint(&loc2[0]);
265 points->InsertNextPoint(&loc3[0]);
269 EXCEPTION(
"PointInTetra only works in 3d");
272 vtkSmartPointer<vtkUnstructuredGrid> p_grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
273 p_grid->SetPoints(points);
274 vtkIdType ptIds[] = {0, 1, 2, 3};
275 p_grid->InsertNextCell(VTK_TETRA, 4, ptIds);
277 vtkSmartPointer<vtkCellLocator> p_locator = vtkSmartPointer<vtkCellLocator>::New();
278 p_locator->SetDataSet(p_grid);
280 c_vector<double, DIM> probe_location = rPoint.
GetLocation(scale_factor);
281 int in_tetra = p_locator->FindCell(&probe_location[0]);
292 template<
unsigned DIM>
298 bool point1_in_box = IsPointInBox<DIM>(rStartPoint, rLocation, spacing);
299 bool point2_in_box = IsPointInBox<DIM>(rEndPoint, rLocation, spacing);
300 if(point1_in_box && point2_in_box)
302 return GetDistance(rEndPoint, rStartPoint);
306 units::quantity<unit::length> scale_factor = rLocation.GetReferenceLengthScale();
307 double dimensionless_spacing = spacing/scale_factor;
309 c_vector<double,6> dimensionless_bounds;
310 c_vector<double, DIM> dimensionless_location = rLocation.GetLocation(scale_factor);
311 dimensionless_bounds[0] = dimensionless_location[0] - dimensionless_spacing/2.0;
312 dimensionless_bounds[1] = dimensionless_location[0] + dimensionless_spacing/2.0;
313 dimensionless_bounds[2] = dimensionless_location[1] - dimensionless_spacing/2.0;
314 dimensionless_bounds[3] = dimensionless_location[1] + dimensionless_spacing/2.0;
317 dimensionless_bounds[4] = dimensionless_location[2] - dimensionless_spacing/2.0;
318 dimensionless_bounds[5] = dimensionless_location[2] + dimensionless_spacing/2.0;
322 dimensionless_bounds[4] = 0.0;
323 dimensionless_bounds[5] = 0.0;
330 c_vector<double,DIM> intercept_1;
331 c_vector<double,DIM> intercept_2;
333 c_vector<double,3> dimensionless_start = rStartPoint.GetLocation(scale_factor);
334 c_vector<double,3> dimensionless_end = rEndPoint.GetLocation(scale_factor);
335 int in_box = vtkBox::IntersectWithLine(&dimensionless_bounds[0], &dimensionless_start[0], &dimensionless_end[0],
336 t1, t2, &intercept_1[0], &intercept_2[0], plane1, plane2);
340 return norm_2(intercept_2 - dimensionless_start)*scale_factor;
345 return norm_2(intercept_1 - dimensionless_end)*scale_factor;
350 return norm_2(intercept_2 - intercept_1)*scale_factor;
354 return 0.0*scale_factor;
359 template<
unsigned DIM>
364 bool point1_in_tetra = IsPointInTetra<DIM>(rStartPoint, locations);
365 bool point2_in_tetra = IsPointInTetra<DIM>(rEndPoint, locations);
367 if(point1_in_tetra && point2_in_tetra)
369 return GetDistance(rEndPoint, rStartPoint);
375 units::quantity<unit::length> scale_factor = rStartPoint.GetReferenceLengthScale();
376 c_vector<double, DIM> loc0 = locations[0].GetLocation(scale_factor);
377 c_vector<double, DIM> loc1 = locations[1].GetLocation(scale_factor);
378 c_vector<double, DIM> loc2 = locations[2].GetLocation(scale_factor);
379 c_vector<double, DIM> loc3 = locations[3].GetLocation(scale_factor);
381 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints> :: New();
382 points->InsertNextPoint(&loc0[0]);
383 points->InsertNextPoint(&loc1[0]);
384 points->InsertNextPoint(&loc2[0]);
385 points->InsertNextPoint(&loc3[0]);
387 vtkSmartPointer<vtkUnstructuredGrid> p_grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
388 p_grid->SetPoints(points);
390 vtkIdType ptIds[] = {0, 1, 2, 3};
391 p_grid->InsertNextCell(VTK_TETRA, 4, ptIds);
394 c_vector<double,DIM> intersection;
395 c_vector<double,DIM> parametric_intersection;
398 c_vector<double,3> dimensionless_start = rStartPoint.GetLocation(scale_factor);
399 c_vector<double,3> dimensionless_end = rEndPoint.GetLocation(scale_factor);
403 p_grid->GetCell(0)->IntersectWithLine(&dimensionless_start[0], &dimensionless_end[0], 1.e-6, t, &intersection[0], ¶metric_intersection[0], subId);
404 return norm_2(intersection - dimensionless_start)*scale_factor;
409 p_grid->GetCell(0)->IntersectWithLine(&dimensionless_end[0], &dimensionless_start[0], 1.e-6, t, &intersection[0], ¶metric_intersection[0], subId);
410 return norm_2(intersection - dimensionless_end)*scale_factor;
413 line_crosses = p_grid->GetCell(0)->IntersectWithLine(&dimensionless_start[0], &dimensionless_end[0], 1.e-6, t, &intersection[0], ¶metric_intersection[0], subId);
416 c_vector<double,DIM> intersection2;
417 p_grid->GetCell(0)->IntersectWithLine(&dimensionless_end[0], &dimensionless_start[0], 1.e-6, t, &intersection2[0], ¶metric_intersection[0], subId);
418 return norm_2(intersection - intersection2)*scale_factor;
422 return 0.0*scale_factor;
427 template<
unsigned DIM>
433 template<
unsigned DIM>
435 units::quantity<unit::length> referenceLength)
440 template<
unsigned DIM>
444 double sin_a = units::sin(angle);
445 double cos_a = units::cos(angle);
446 c_vector<double, DIM> new_direction;
448 c_vector<double, DIM> dimensionless_direction = rDirection.
GetLocation(length_scale);
452 units::quantity<unit::length> dot_product = GetDotProduct(rDirection, unit_axis);
453 double dimensionless_dot_product = dot_product/length_scale;
454 new_direction[0] = (unit_axis[0] * dimensionless_dot_product * (1.0 - cos_a) + dimensionless_direction[0] * cos_a
455 + (-unit_axis[2] * dimensionless_direction[1] + unit_axis[1] * dimensionless_direction[2]) * sin_a);
456 new_direction[1] = (unit_axis[1] * dimensionless_dot_product * (1.0 - cos_a) + dimensionless_direction[1] * cos_a
457 + (unit_axis[2] * dimensionless_direction[0] - unit_axis[0] * dimensionless_direction[2]) * sin_a);
458 new_direction[2] = (unit_axis[2] * dimensionless_dot_product * (1.0 - cos_a) + dimensionless_direction[2] * cos_a
459 + (-unit_axis[1] * dimensionless_direction[0] + unit_axis[0] * dimensionless_direction[1]) * sin_a);
463 new_direction[0] = dimensionless_direction[0] * cos_a - dimensionless_direction[1]*sin_a;
464 new_direction[1] = dimensionless_direction[0] * sin_a + dimensionless_direction[1]*cos_a;
469 template<
unsigned DIM>
470 c_vector<double, DIM> RotateAboutAxis(
const c_vector<double, DIM>& rDirection,
471 const c_vector<double, 3>& rAxis, units::quantity<unit::plane_angle> angle)
473 double sin_a = units::sin(angle);
474 double cos_a = units::cos(angle);
475 c_vector<double, DIM> new_direction = zero_vector<double>(DIM);
479 c_vector<double, 3> unit_axis = rAxis/norm_2(rAxis);
480 double dot_product = inner_prod(rDirection, unit_axis);
481 new_direction[0] = (unit_axis[0] * dot_product * (1.0 - cos_a) + rDirection[0] * cos_a
482 + (-unit_axis[2] * rDirection[1] + unit_axis[1] * rDirection[2]) * sin_a);
483 new_direction[1] = (unit_axis[1] * dot_product * (1.0 - cos_a) + rDirection[1] * cos_a
484 + (unit_axis[2] * rDirection[0] - unit_axis[0] * rDirection[2]) * sin_a);
485 new_direction[2] = (unit_axis[2] * dot_product * (1.0 - cos_a) + rDirection[2] * cos_a
486 + (-unit_axis[1] * rDirection[0] + unit_axis[0] * rDirection[1]) * sin_a);
490 new_direction[0] = rDirection[0] * cos_a - rDirection[1]*sin_a;
491 new_direction[1] = rDirection[0] * sin_a + rDirection[1]*cos_a;
493 return new_direction;
units::quantity< unit::length > GetReferenceLengthScale() const
units::quantity< unit::length > GetDistance(const DimensionalChastePoint< DIM > &rLocation) const
c_vector< double, DIM > GetUnitVector() const
c_vector< double, DIM > GetLocation(units::quantity< unit::length > scale)
units::quantity< unit::length > GetNorm2()