31 #define OMPI_SKIP_MPICXX 1 32 #define MPICH_SKIP_MPICXX 84 const size_t pointNo = point_list.size();
89 for (
size_t i=0; i<pointNo; i++)
92 if (point_list[j][1] <= point[1])
95 if (
approx(point_list[i][0],point[0]) &&
approx(point_list[i][1],point[1]))
98 if (point_list[i][1] >= point[1])
100 const double is_left = (point_list[i][0] - point_list[j][0]) * (point[1] - point_list[j][1])
101 - (point[0] - point_list[j][0]) * (point_list[i][1] - point_list[j][1]);
103 if ( is_left > 0 && point_list[i][1] > point[1])
108 else if ( std::abs(is_left) < std::numeric_limits<double>::epsilon())
112 const double dot_product = (point - point_list[j])*(point_list[i] - point_list[j]);
114 if (dot_product >= 0)
116 const double squaredlength = (point_list[i] - point_list[j]).norm_square();
118 if (dot_product <= squaredlength)
129 if (point_list[i][1] <= point[1])
131 const double is_left = (point_list[i][0] - point_list[j][0]) * (point[1] - point_list[j][1])
132 - (point[0] - point_list[j][0]) * (point_list[i][1] - point_list[j][1]);
139 else if (std::abs(is_left) < std::numeric_limits<double>::epsilon())
144 const double dot_product = (point - point_list[j])*(point_list[i] - point_list[j]);
146 if (dot_product >= 0)
148 const double squaredlength = (point_list[i] - point_list[j]).norm_square();
150 if (dot_product <= squaredlength)
168 const double semi_major_axis,
169 const double eccentricity,
173 const double x_rotated = (point[0] - ellipse_center[0]) *
std::cos(theta) + (point[1] - ellipse_center[1])*
std::sin(theta);
174 const double y_rotated = -(point[0] - ellipse_center[0]) *
std::sin(theta) + (point[1] - ellipse_center[1])*
std::cos(theta);
176 const double semi_minor_axis = semi_major_axis * std::sqrt(1 - std::pow(eccentricity, 2));
178 if (semi_major_axis < 10 * std::numeric_limits<double>::min()
179 || semi_minor_axis < 10 * std::numeric_limits<double>::min())
182 const double ellipse = std::pow((x_rotated), 2) / std::pow(semi_major_axis, 2)
183 + std::pow((y_rotated), 2) / std::pow(semi_minor_axis, 2);
211 const size_t n_poly_points = point_list.size();
212 WBAssertThrow(n_poly_points >= 3,
"Not enough polygon points were specified.");
215 std::vector<double> distances(n_poly_points, 1e23);
219 shifted_point_list[0] = point_list[n_poly_points-1];
221 for (
size_t i = 0; i < n_poly_points-1; ++i)
222 shifted_point_list[i+1] = point_list[i];
224 for (
size_t i = 0; i < n_poly_points; ++i)
227 const Point<2> vector_segment = shifted_point_list[i] - point_list[i];
229 const Point<2> vector_point_segment = point - point_list[i];
232 const double c1 = vector_point_segment * vector_segment;
233 const double c2 = vector_segment * vector_segment;
237 distances[i] = (
Point<2> (point_list[i] - point)).
norm();
240 distances[i] = (
Point<2> (shifted_point_list[i] - point)).norm();
244 const Point<2> point_on_segment = point_list[i] + (c1/c2) * vector_segment;
245 distances[i] = (
Point<2> (point - point_on_segment)).
norm();
250 return *std::min_element(distances.begin(),distances.end()) * sign;
257 std::array<double,3> scoord;
259 scoord[0] = position.
norm();
260 scoord[1] = std::atan2(position[1],position[0]);
265 if (scoord[0] > std::numeric_limits<double>::min())
266 scoord[2] = 0.5 *
Consts::PI - std::acos(position[2]/scoord[0]);
289 if (coordinate_system ==
"cartesian")
291 if (coordinate_system ==
"spherical")
299 template<
unsigned int dim>
300 std::array<double,dim>
303 std::array<double,dim> array;
304 for (
size_t i = 0; i < dim; ++i)
305 array[i] = point_[i];
313 std::string s = string;
314 while ((!s.empty()) && (s[0] ==
' '))
316 while ((!s.empty()) && (s[s.size() - 1] ==
' '))
317 s.erase(s.end() - 1);
319 std::istringstream i(s);
322 if (!(i >> d) || i.get(c))
323 WBAssertThrow(
false,
"Could not convert \"" + s +
"\" to a double.");
332 std::string s = string;
333 while ((!s.empty()) && (s[0] ==
' '))
335 while ((!s.empty()) && (s[s.size() - 1] ==
' '))
336 s.erase(s.end() - 1);
338 std::istringstream i(s);
341 if (!(i >> d) || i.get(c))
342 WBAssertThrow(
false,
"Could not convert \"" + s +
"\" to an int.");
352 std::string s = string;
353 while ((!s.empty()) && (s[0] ==
' '))
355 while ((!s.empty()) && (s[s.size() - 1] ==
' '))
356 s.erase(s.end() - 1);
359 std::istringstream i(s);
362 if (!(i >> d) || i.get(c))
363 WBAssertThrow(
false,
"Could not convert \"" + s +
"\" to an unsigned int.");
373 const double x = a[1] * b[2] - b[1] * a[2];
374 const double y = a[2] * b[0] - b[2] * a[0];
375 const double z = a[0] * b[1] - b[0] * a[1];
376 return Point<3>(x,y,z,a.get_coordinate_system());
383 const std::vector<
Point<2> > &point_list,
384 const std::vector<std::vector<double> > &plane_segment_lengths,
385 const std::vector<std::vector<
Point<2> > > &plane_segment_angles,
386 const double start_radius,
387 const std::unique_ptr<CoordinateSystems::Interface> &coordinate_system,
388 const bool only_positive,
391 double distance = std::numeric_limits<double>::infinity();
392 double new_distance = std::numeric_limits<double>::infinity();
393 double along_plane_distance = std::numeric_limits<double>::infinity();
394 double new_along_plane_distance = std::numeric_limits<double>::infinity();
395 double new_depth_reference_surface = std::numeric_limits<double>::infinity();
397 const CoordinateSystem natural_coordinate_system = coordinate_system->natural_coordinate_system();
398 const bool bool_cartesian = natural_coordinate_system ==
cartesian;
400 const std::array<double,3> &check_point_surface_2d_array = natural_coordinate.
get_coordinates();
401 const Point<3> check_point_surface(bool_cartesian ? check_point_surface_2d_array[0] : start_radius,
402 check_point_surface_2d_array[1],
403 bool_cartesian ? start_radius : check_point_surface_2d_array[2],
404 natural_coordinate_system);
406 natural_coordinate_system);
412 double section_fraction = 0.0;
419 double segment_fraction = 0.0;
420 double total_average_angle = 0.0;
421 double depth_reference_surface = 0.0;
423 const DepthMethod depth_method = coordinate_system->depth_method();
425 size_t i_section_min_distance = 0;
426 double fraction_CPL_P1P2 = std::numeric_limits<double>::infinity();
435 Point<2> closest_point_on_line_2d = closest_point_on_curve.
point;
440 const Point<3> closest_point_on_line_surface(bool_cartesian ? closest_point_on_line_2d[0] : start_radius,
441 bool_cartesian ? closest_point_on_line_2d[1] : closest_point_on_line_2d[0],
442 bool_cartesian ? start_radius : closest_point_on_line_2d[1],
443 natural_coordinate_system);
445 const Point<3> closest_point_on_line_cartesian(coordinate_system->natural_to_cartesian_coordinates(closest_point_on_line_surface.
get_array()),
cartesian);
447 if (!std::isnan(closest_point_on_line_2d[0]))
449 i_section_min_distance = closest_point_on_curve.
index;
452 Point<3> closest_point_on_line_bottom = closest_point_on_line_surface;
453 closest_point_on_line_bottom[bool_cartesian ? 2 : 0] = 0;
455 WBAssert(!std::isnan(closest_point_on_line_bottom[0])
457 !std::isnan(closest_point_on_line_bottom[1])
459 !std::isnan(closest_point_on_line_bottom[2]),
460 "Internal error: The closest_point_on_line_bottom variables variable contains not a number: " << closest_point_on_line_bottom);
464 const Point<3> closest_point_on_line_bottom_cartesian(coordinate_system->natural_to_cartesian_coordinates(closest_point_on_line_bottom.
get_array()),
cartesian);
465 const Point<3> check_point_surface_cartesian(coordinate_system->natural_to_cartesian_coordinates(check_point_surface.
get_array()),
cartesian);
468 WBAssert(!std::isnan(closest_point_on_line_bottom_cartesian[0]),
469 "Internal error: The closest_point_on_line_bottom_cartesian[0] variable is not a number: " << closest_point_on_line_bottom_cartesian[0]);
470 WBAssert(!std::isnan(closest_point_on_line_bottom_cartesian[1]),
471 "Internal error: The closest_point_on_line_bottom_cartesian[1] variable is not a number: " << closest_point_on_line_bottom_cartesian[1]);
472 WBAssert(!std::isnan(closest_point_on_line_bottom_cartesian[2]),
473 "Internal error: The closest_point_on_line_bottom_cartesian[2] variable is not a number: " << closest_point_on_line_bottom_cartesian[2]);
477 const size_t original_current_section = i_section_min_distance;
478 const size_t original_next_section = original_current_section + 1;
483 Point<3> y_axis = closest_point_on_line_cartesian - closest_point_on_line_bottom_cartesian;
484 Point<3> x_axis = closest_point_on_line_cartesian - check_point_surface_cartesian;
490 if (std::fabs((check_point_surface - closest_point_on_line_surface).norm()) < 2e-14)
493 if (std::fabs((check_point - closest_point_on_line_cartesian).norm()) > 2e-14)
495 const Point<2> &P1(point_list[i_section_min_distance]);
496 const Point<2> &P2(point_list[i_section_min_distance+1]);
499 const Point<2> unit_normal_to_plane_spherical = P1P2 / P1P2.
norm();
500 const Point<2> closest_point_on_line_plus_normal_to_plane_spherical = closest_point_on_line_2d + 1e-8 * (closest_point_on_line_2d.norm() > 1.0 ? closest_point_on_line_2d.norm() : 1.0) * unit_normal_to_plane_spherical;
502 WBAssert(std::fabs(closest_point_on_line_plus_normal_to_plane_spherical.
norm()) > std::numeric_limits<double>::epsilon(),
503 "Internal error: The norm of variable 'closest_point_on_line_plus_normal_to_plane_spherical' " 504 "is zero, while this may not happen.");
506 const Point<3> closest_point_on_line_plus_normal_to_plane_surface_spherical(bool_cartesian ? closest_point_on_line_plus_normal_to_plane_spherical[0] : start_radius,
507 bool_cartesian ? closest_point_on_line_plus_normal_to_plane_spherical[1] : closest_point_on_line_plus_normal_to_plane_spherical[0],
508 bool_cartesian ? start_radius : closest_point_on_line_plus_normal_to_plane_spherical[1],
509 natural_coordinate_system);
510 const Point<3> closest_point_on_line_plus_normal_to_plane_cartesian(coordinate_system->natural_to_cartesian_coordinates(closest_point_on_line_plus_normal_to_plane_surface_spherical.get_array()),
cartesian);
511 Point<3> normal_to_plane = closest_point_on_line_plus_normal_to_plane_cartesian - closest_point_on_line_cartesian;
512 normal_to_plane = normal_to_plane / normal_to_plane.
norm();
518 y_axis = closest_point_on_line_cartesian - closest_point_on_line_bottom_cartesian;
520 WBAssert(std::abs(y_axis.
norm()) > std::numeric_limits<double>::epsilon(),
521 "World Builder error: Cannot determine the up direction in the model. This is most likely due to the provided start radius being zero." 522 <<
" Technical details: The y_axis.norm() is zero. Y_axis is " << y_axis[0] <<
':' << y_axis[1] <<
':' << y_axis[2]
523 <<
". closest_point_on_line_cartesian = " << closest_point_on_line_cartesian[0] <<
':' << closest_point_on_line_cartesian[1] <<
':' << closest_point_on_line_cartesian[2]
524 <<
", closest_point_on_line_bottom_cartesian = " << closest_point_on_line_bottom_cartesian[0] <<
':' << closest_point_on_line_bottom_cartesian[1] <<
':' << closest_point_on_line_bottom_cartesian[2]);
527 "Internal error: The y_axis variable is not a number: " << y_axis[0]);
529 "Internal error: The y_axis variable is not a number: " << y_axis[1]);
531 "Internal error: The y_axis variable is not a number: " << y_axis[2]);
533 y_axis = y_axis / y_axis.
norm();
536 "Internal error: The y_axis variable is not a number: " << y_axis[0]);
538 "Internal error: The y_axis variable is not a number: " << y_axis[1]);
540 "Internal error: The y_axis variable is not a number: " << y_axis[2]);
544 const double vx = y_axis[0];
545 const double vy = y_axis[1];
546 const double vz = y_axis[2];
547 const double ux = normal_to_plane[0];
548 const double uy = normal_to_plane[1];
549 const double uz = normal_to_plane[2];
551 x_axis =
Point<3>(ux*ux*vx + ux*uy*vy - uz*vy + uy*uz*vz + uy*vz,
552 uy*ux*vx + uz*vx + uy*uy*vy + uy*uz*vz - ux*vz,
553 uz*ux*vx - uy*vx + uz*uy*vy + ux*vy + uz*uz*vz,
557 const Point<2> reference_p = ((closest_point_on_curve.
normal-closest_point_on_line_2d)*1e2)+closest_point_on_line_2d;
558 const double reference_on_side_of_line = (closest_point_on_line_2d-reference_p).norm_square() < (check_point_surface_2d-reference_p).norm_square() ? -1 : 1;
561 "Internal error: The x_axis variable is not a number: " << x_axis[0]);
563 "Internal error: The x_axis variable is not a number: " << x_axis[1]);
565 "Internal error: The x_axis variable is not a number: " << x_axis[2]);
567 x_axis = x_axis *(reference_on_side_of_line / x_axis.
norm());
570 "Internal error: The x_axis variable is not a number: " << x_axis[0]);
572 "Internal error: The x_axis variable is not a number: " << x_axis[1]);
574 "Internal error: The x_axis variable is not a number: " << x_axis[2]);
578 total_average_angle = plane_segment_angles[original_current_section][0][0]
579 + fraction_CPL_P1P2 * (plane_segment_angles[original_next_section][0][0]
580 - plane_segment_angles[original_current_section][0][0]);
584 return_values.distance_along_plane = 0.0;
585 return_values.fraction_of_section = fraction_CPL_P1P2;
586 return_values.fraction_of_segment = 0.0;
587 return_values.section = i_section_min_distance;
588 return_values.segment = 0;
589 return_values.average_angle = total_average_angle;
590 return_values.depth_reference_surface = 0.0;
591 return_values.closest_trench_point = closest_point_on_line_cartesian;
592 return return_values;
597 WBAssert(std::abs(y_axis.
norm()) > std::numeric_limits<double>::epsilon(),
598 "World Builder error: Cannot determine the up direction in the model. This is most likely due to the provided start radius being zero." 599 <<
" Technical details: The y_axis.norm() is zero. Y_axis is " << y_axis
600 <<
". closest_point_on_line_cartesian = " << closest_point_on_line_cartesian
601 <<
", closest_point_on_line_bottom_cartesian = " << closest_point_on_line_bottom_cartesian);
604 "Internal error: The y_axis variable is not a number: " << y_axis[0]);
606 "Internal error: The y_axis variable is not a number: " << y_axis[1]);
608 "Internal error: The y_axis variable is not a number: " << y_axis[2]);
610 y_axis = y_axis / y_axis.
norm();
613 "Internal error: The y_axis variable is not a number: " << y_axis[0]);
615 "Internal error: The y_axis variable is not a number: " << y_axis[1]);
617 "Internal error: The y_axis variable is not a number: " << y_axis[2]);
620 Point<2> check_point_surface_2d_temp = check_point_surface_2d;
624 const double normal = std::fabs(point_list[i_section_min_distance+static_cast<size_t>(std::round(fraction_CPL_P1P2))][0]-check_point_surface_2d[0]);
625 const double plus = std::fabs(point_list[i_section_min_distance+static_cast<size_t>(std::round(fraction_CPL_P1P2))][0]-(check_point_surface_2d[0]+2*
Consts::PI));
626 const double min = std::fabs(point_list[i_section_min_distance+static_cast<size_t>(std::round(fraction_CPL_P1P2))][0]-(check_point_surface_2d[0]-2*
Consts::PI));
631 check_point_surface_2d_temp[0]+= 2*
Consts::PI;
633 else if (min < normal)
635 check_point_surface_2d_temp[0]-= 2*
Consts::PI;
640 const Point<2> AB_normal = closest_point_on_curve.
normal*closest_point_on_line_2d.
distance(reference_point);
641 const Point<2> local_reference_point = AB_normal*1.+closest_point_on_line_2d;
642 const bool reference_normal_on_side_of_line = (closest_point_on_line_2d-local_reference_point).norm_square() < (check_point_surface_2d_temp-local_reference_point).norm_square();
643 const bool reference_point_on_side_of_line = (point_list[point_list.size()-1][0] - point_list[0][0])*(reference_point[1] - point_list[0][1]) - (reference_point[0] - point_list[0][0])*(point_list[point_list.size()-1][1] - point_list[0][1]) < 0.;
644 const double reference_on_side_of_line = reference_normal_on_side_of_line == reference_point_on_side_of_line ? 1 : -1;
647 "Internal error: The x_axis variable is not a number: " << x_axis[0]);
649 "Internal error: The x_axis variable is not a number: " << x_axis[1]);
651 "Internal error: The x_axis variable is not a number: " << x_axis[2]);
655 x_axis = x_axis *(reference_on_side_of_line / x_axis.norm());
658 "Internal error: The x_axis variable is not a number: " << x_axis[0]);
660 "Internal error: The x_axis variable is not a number: " << x_axis[1]);
662 "Internal error: The x_axis variable is not a number: " << x_axis[2]);
667 "Internal error: The x_axis[0] variable is not a number: " << x_axis[0] <<
". Relevant values: check_point = " << check_point <<
'.');
669 "Internal error: The x_axis[1] variable is not a number: " << x_axis[1]);
671 "Internal error: The x_axis[2] variable is not a number: " << x_axis[2]);
674 Point<2> check_point_2d(x_axis * (check_point - closest_point_on_line_bottom_cartesian),
675 y_axis * (check_point - closest_point_on_line_bottom_cartesian),
678 Point<2> begin_segment(x_axis * (closest_point_on_line_cartesian - closest_point_on_line_bottom_cartesian),
679 y_axis * (closest_point_on_line_cartesian - closest_point_on_line_bottom_cartesian),
682 WBAssert(!std::isnan(check_point_2d[0]),
683 "Internal error: The check_point_2d variable is not a number: " << check_point_2d[0]);
684 WBAssert(!std::isnan(check_point_2d[1]),
685 "Internal error: The check_point_2d variable is not a number: " << check_point_2d[1]);
688 WBAssert(!std::isnan(begin_segment[0]),
689 "Internal error: The begin_segment variable is not a number: " << begin_segment[0]);
690 WBAssert(!std::isnan(begin_segment[1]),
691 "Internal error: The begin_segment variable is not a number: " << begin_segment[1]);
693 Point<2> end_segment = begin_segment;
695 double total_length = 0.0;
696 double add_angle = 0.0;
697 double add_angle_correction = 0.0;
698 double average_angle = 0.0;
699 for (
size_t i_segment = 0; i_segment < plane_segment_lengths[original_current_section].size(); i_segment++)
701 const size_t current_segment = i_segment;
711 double add_angle_inner = (begin_segment * end_segment) / (begin_segment.
norm() * end_segment.
norm());
713 WBAssert(!std::isnan(add_angle_inner),
714 "Internal error: The add_angle_inner variable is not a number: " << add_angle_inner
715 <<
". Variables: begin_segment = " << begin_segment
716 <<
", end_segment = " << end_segment
717 <<
", begin_segment * end_segment / (begin_segment.norm() * end_segment.norm()) = " 718 << std::setprecision(32) << begin_segment * end_segment / (begin_segment.
norm() * end_segment.
norm())
722 if (add_angle_inner < 0. && add_angle_inner >= -1e-14)
723 add_angle_inner = 0.;
724 if (add_angle_inner > 1. && add_angle_inner <= 1.+1e-14)
725 add_angle_inner = 1.;
727 WBAssert(add_angle_inner >= 0 && add_angle_inner <= 1,
728 "Internal error: The variable add_angle_inner is smaller than zero or larger then one," 729 "which causes the std::acos to return nan. If it is only a little bit larger then one, " 730 "this is probably caused by that begin and end segment are the same and round off error. " 731 "The value of add_angle_inner = " << add_angle_inner);
733 add_angle_correction = std::acos(add_angle_inner);
734 add_angle += add_angle_correction;
737 "Internal error: The add_angle variable is not a number: " << add_angle
738 <<
". Variables: begin_segment = " << begin_segment
739 <<
", end_segment = " << end_segment
740 <<
", begin_segment * end_segment / (begin_segment.norm() * end_segment.norm()) = " 741 << std::setprecision(32) << begin_segment * end_segment / (begin_segment.
norm() * end_segment.
norm())
742 <<
", std::acos(begin_segment * end_segment / (begin_segment.norm() * end_segment.norm())) = " 743 << std::acos(begin_segment * end_segment / (begin_segment.
norm() * end_segment.
norm())));
749 begin_segment = end_segment;
751 WBAssert(!std::isnan(begin_segment[0]),
752 "Internal error: The begin_segment variable is not a number: " << begin_segment[0]);
753 WBAssert(!std::isnan(begin_segment[1]),
754 "Internal error: The begin_segment variable is not a number: " << begin_segment[1]);
759 const double degree_90_to_rad = 0.5 *
Consts::PI;
761 WBAssert(plane_segment_angles.size() > original_next_section,
762 "Error: original_next_section = " << original_next_section
763 <<
", and plane_segment_angles.size() = " << plane_segment_angles.size());
766 WBAssert(plane_segment_angles[original_next_section].size() > current_segment,
767 "Error: current_segment = " << current_segment
768 <<
", and current_segment.size() = " << plane_segment_angles[original_next_section].size());
770 const double interpolated_angle_top = plane_segment_angles[original_current_section][current_segment][0]
771 + fraction_CPL_P1P2 * (plane_segment_angles[original_next_section][current_segment][0]
772 - plane_segment_angles[original_current_section][current_segment][0])
775 && i_segment != 0 ? -add_angle_correction: 0);
777 const double interpolated_angle_bottom = plane_segment_angles[original_current_section][current_segment][1]
778 + fraction_CPL_P1P2 * (plane_segment_angles[original_next_section][current_segment][1]
779 - plane_segment_angles[original_current_section][current_segment][1])
783 const double interpolated_segment_length = plane_segment_lengths[original_current_section][current_segment]
784 + fraction_CPL_P1P2 * (plane_segment_lengths[original_next_section][current_segment]
785 - plane_segment_lengths[original_current_section][current_segment]);
787 if (interpolated_segment_length < 1e-14)
790 WBAssert(!std::isnan(interpolated_angle_top),
791 "Internal error: The interpolated_angle_top variable is not a number: " << interpolated_angle_top);
797 const double difference_in_angle_along_segment = interpolated_angle_top - interpolated_angle_bottom;
799 if (std::fabs(difference_in_angle_along_segment) < 1e-8)
803 if (std::fabs(interpolated_segment_length) > std::numeric_limits<double>::epsilon())
805 end_segment[0] += interpolated_segment_length *
std::sin(degree_90_to_rad - interpolated_angle_top);
806 end_segment[1] -= interpolated_segment_length *
std::cos(degree_90_to_rad - interpolated_angle_top);
808 Point<2> begin_end_segment = end_segment - begin_segment;
810 WBAssert(std::fabs(normal_2d_plane.
norm()) > std::numeric_limits<double>::epsilon(),
"Internal Error: normal_2d_plane.norm() is zero, which should not happen. " 811 <<
"Extra info: begin_end_segment[0] = " << begin_end_segment[0]
812 <<
", begin_end_segment[1] = " << begin_end_segment[1]
813 <<
", end_segment: [" << end_segment[0] <<
',' << end_segment[1] <<
']' 814 <<
", begin_segment: [" << begin_segment[0] <<
',' << begin_segment[1] <<
']' 816 normal_2d_plane /= normal_2d_plane.
norm();
820 const Point<2> BSP_ESP = end_segment - begin_segment;
821 const Point<2> BSP_CP = check_point_2d - begin_segment;
823 const double c1 = BSP_ESP * BSP_CP;
824 const double c2 = BSP_ESP * BSP_ESP;
826 if (c1 < 0 || c2 < c1)
828 new_distance = std::numeric_limits<double>::infinity();
829 new_along_plane_distance = std::numeric_limits<double>::infinity();
830 new_depth_reference_surface = std::numeric_limits<double>::infinity();
834 const Point<2> Pb = begin_segment + (c1/c2) * BSP_ESP;
835 const double side_of_line = (begin_segment[0] - end_segment[0]) * (check_point_2d[1] - begin_segment[1])
836 - (begin_segment[1] - end_segment[1]) * (check_point_2d[0] - begin_segment[0])
839 new_distance = side_of_line * (check_point_2d - Pb).norm();
840 new_along_plane_distance = (begin_segment - Pb).norm();
841 new_depth_reference_surface = start_radius - Pb[1];
843 WBAssert(!std::isnan(new_depth_reference_surface),
844 "new_depth_reference_surface is not a number: " << new_depth_reference_surface <<
". " 845 <<
"start_radius = " << start_radius <<
",Pb[1] = " << Pb[1] <<
".");
853 const double radius_angle_circle = std::fabs(interpolated_segment_length/difference_in_angle_along_segment);
855 WBAssert(!std::isnan(radius_angle_circle),
856 "Internal error: The radius_angle_circle variable is not a number: " << radius_angle_circle
857 <<
". interpolated_segment_length = " << interpolated_segment_length
858 <<
", difference_in_angle_along_segment = " << difference_in_angle_along_segment);
860 const double cos_angle_top =
std::cos(interpolated_angle_top);
862 WBAssert(!std::isnan(cos_angle_top),
863 "Internal error: The radius_angle_circle variable is not a number: " << cos_angle_top
864 <<
". interpolated_angle_top = " << interpolated_angle_top);
867 if (std::fabs(interpolated_angle_top - 0.5 *
Consts::PI) < 1e-8)
873 center_circle[0] = difference_in_angle_along_segment > 0 ? begin_segment[0] + radius_angle_circle : begin_segment[0] - radius_angle_circle;
874 center_circle[1] = begin_segment[1];
876 else if (std::fabs(interpolated_angle_top - 1.5 *
Consts::PI) < 1e-8)
882 center_circle[0] = difference_in_angle_along_segment > 0 ? begin_segment[0] - radius_angle_circle : begin_segment[0] + radius_angle_circle;
883 center_circle[1] = begin_segment[1];
887 const double tan_angle_top = std::tan(interpolated_angle_top);
889 WBAssert(!std::isnan(tan_angle_top),
890 "Internal error: The tan_angle_top variable is not a number: " << tan_angle_top);
891 const double center_circle_y = difference_in_angle_along_segment < 0 ?
892 begin_segment[1] - radius_angle_circle * cos_angle_top
893 : begin_segment[1] + radius_angle_circle * cos_angle_top;
895 WBAssert(!std::isnan(center_circle_y),
896 "Internal error: The center_circle_y variable is not a number: " << center_circle_y
897 <<
". begin_segment[1] = " << begin_segment[1]
898 <<
", radius_angle_circle = " << radius_angle_circle
899 <<
", cos_angle_top = " << cos_angle_top);
904 const double CCYBS = center_circle_y - begin_segment[1];
907 "Internal error: The CCYBS variable is not a number: " << CCYBS);
911 center_circle[0] = begin_segment[0] + tan_angle_top * (CCYBS);
912 center_circle[1] = center_circle_y;
915 WBAssert(!std::isnan(center_circle[0]) || !std::isnan(center_circle[1]),
916 "Internal error: The center variable contains not a number: " << center_circle[0] <<
':' << center_circle[0]);
917 WBAssert(std::fabs((begin_segment-center_circle).norm() - std::fabs(radius_angle_circle))
918 < 1e-8 * std::fabs((begin_segment-center_circle).norm() + std::fabs(radius_angle_circle)),
919 "Internal error: The center of the circle is not a radius away from the begin point. " << std::endl
920 <<
"The center is located at " << center_circle[0] <<
':' << center_circle[1] << std::endl
921 <<
"The begin point is located at " << begin_segment[0] <<
':' << begin_segment[1] << std::endl
922 <<
"The computed radius is " << std::fabs((begin_segment-center_circle).norm())
923 <<
", and it should be " << radius_angle_circle <<
'.');
928 Point<2> BSPC = begin_segment - center_circle;
929 const double sin_angle_diff =
sin(difference_in_angle_along_segment);
930 const double cos_angle_diff =
cos(difference_in_angle_along_segment);
931 end_segment[0] = cos_angle_diff * BSPC[0] - sin_angle_diff * BSPC[1] + center_circle[0];
932 end_segment[1] = sin_angle_diff * BSPC[0] + cos_angle_diff * BSPC[1] + center_circle[1];
936 WBAssert(std::fabs((end_segment-center_circle).norm() - std::fabs(radius_angle_circle))
937 < 1e-8 * std::fabs((end_segment-center_circle).norm() + std::fabs(radius_angle_circle)) ,
938 "Internal error: The center of the circle is not a radius away from the end point. " << std::endl
939 <<
"The center is located at " << center_circle[0] <<
':' << center_circle[1] << std::endl
940 <<
"The end point is located at " << end_segment[0] <<
':' << end_segment[1] << std::endl
941 <<
"The computed radius is " << std::fabs((end_segment-center_circle).norm())
942 <<
", and it should be " << radius_angle_circle <<
'.');
952 const Point<2> CPCR = check_point_2d - center_circle;
953 const double CPCR_norm = CPCR.
norm();
963 double check_point_angle = std::fabs(CPCR_norm) < std::numeric_limits<double>::epsilon() ? 2.0 *
Consts::PI : (check_point_2d[0] <= center_circle[0]
964 ? std::acos(dot_product/(CPCR_norm * radius_angle_circle))
965 : 2.0 *
Consts::PI - std::acos(dot_product/(CPCR_norm * radius_angle_circle)));
966 check_point_angle = difference_in_angle_along_segment >= 0 ?
Consts::PI - check_point_angle : 2.0 *
Consts::PI - check_point_angle;
969 check_point_angle = (std::fabs(check_point_angle - 2 *
Consts::PI) < 1e-14 ? 0 : check_point_angle);
971 if ((difference_in_angle_along_segment > 0 && (check_point_angle <= interpolated_angle_top || std::fabs(check_point_angle - interpolated_angle_top) < 1e-12)
972 && (check_point_angle >= interpolated_angle_bottom || std::fabs(check_point_angle - interpolated_angle_bottom) < 1e-12))
973 || (difference_in_angle_along_segment < 0 && (check_point_angle >= interpolated_angle_top || std::fabs(check_point_angle - interpolated_angle_top) < 1e-12)
974 && (check_point_angle <= interpolated_angle_bottom || std::fabs(check_point_angle - interpolated_angle_bottom) < 1e-12)))
976 new_distance = (radius_angle_circle - CPCR_norm) * (difference_in_angle_along_segment < 0 ? 1 : -1);
977 new_along_plane_distance = (radius_angle_circle * check_point_angle - radius_angle_circle * interpolated_angle_top) * (difference_in_angle_along_segment < 0 ? 1 : -1);
979 new_depth_reference_surface = start_radius-(
sin(check_point_angle + interpolated_angle_top) * BSPC[0] +
cos(check_point_angle + interpolated_angle_top) * BSPC[1] + center_circle[1]);
981 WBAssert(!std::isnan(new_depth_reference_surface),
982 "new_depth_reference_surface is not a number: " << new_depth_reference_surface <<
". " 983 <<
"start_radius = " << start_radius <<
", check_point_angle = " << check_point_angle <<
", interpolated_angle_top = " << interpolated_angle_top
984 <<
", BSPC[0] = " << BSPC[0] <<
".");
994 if (new_along_plane_distance >= -1e-10 &&
995 new_along_plane_distance <= std::fabs(interpolated_segment_length) &&
996 std::fabs(new_distance) < std::fabs(distance))
1002 distance = only_positive ? std::fabs(new_distance) : new_distance;
1003 along_plane_distance = new_along_plane_distance + total_length;
1004 section = i_section_min_distance;
1005 section_fraction = fraction_CPL_P1P2;
1006 segment = i_segment;
1007 segment_fraction = new_along_plane_distance / interpolated_segment_length;
1008 total_average_angle = (average_angle * total_length
1009 + 0.5 * (interpolated_angle_top + interpolated_angle_bottom - 2 * add_angle) * new_along_plane_distance);
1010 total_average_angle = (std::fabs(total_average_angle) < std::numeric_limits<double>::epsilon() ? 0 : total_average_angle /
1011 (total_length + new_along_plane_distance));
1012 depth_reference_surface = new_depth_reference_surface;
1016 average_angle = (average_angle * total_length +
1017 0.5 * (interpolated_angle_top + interpolated_angle_bottom - 2 * add_angle) * interpolated_segment_length);
1018 average_angle = (std::fabs(average_angle) < std::numeric_limits<double>::epsilon() ? 0 : average_angle /
1019 (total_length + interpolated_segment_length));
1021 total_length += interpolated_segment_length;
1025 WBAssert(!std::isnan(depth_reference_surface),
"depth_reference_surface is not a number: " << depth_reference_surface <<
".");
1029 return_values.distance_along_plane = along_plane_distance;
1030 return_values.fraction_of_section = section_fraction;
1031 return_values.fraction_of_segment = segment_fraction;
1032 return_values.section = section;
1033 return_values.segment = segment;
1034 return_values.average_angle = total_average_angle;
1035 return_values.depth_reference_surface = depth_reference_surface;
1036 return_values.closest_trench_point = closest_point_on_line_cartesian;
1037 return return_values;
1042 const size_t n = y.size();
1045 for (
unsigned int i = 0; i < n; ++i)
1060 for (
size_t i = 0; i < n-2; i++)
1062 const double m0 = y[i+1]-y[i];
1063 const double m1 = y[i+2]-y[i+1];
1071 m[i+1][2] = 2*m0*m1/(m0+m1);
1074 m[n-1][2] = y[n-1]-y[n-2];
1079 for (
size_t i = 0; i < n-1; i++)
1081 const double c1 =
m[i][2];
1082 const double m0 = y[i+1]-y[i];
1084 const double common0 = c1 +
m[i+1][2] - m0 - m0;
1085 m[i][1] = (m0 - c1 - common0);
1092 return angle - 360.0*std::floor(angle/360.0);
1096 const double angle_2,
1097 const double fraction)
1099 double theta_1 = angle_1;
1100 double theta_2 = angle_2;
1101 double rotation_angle;
1103 if (std::abs(theta_2 - theta_1) >
Consts::PI)
1105 if (theta_2 > theta_1)
1110 rotation_angle = (1-fraction) * theta_1 + fraction * theta_2;
1115 return rotation_angle;
1118 std::array<double,3>
1121 const double rad_to_degree = 180.0/
Consts::PI;
1122 std::array<double,3> euler_angles;
1124 const std::ostringstream os;
1125 for (
size_t i = 0; i < 3; i++)
1126 for (
size_t j = 0; j < 3; j++)
1127 WBAssert(std::fabs(rotation_matrix[i][j]) <= 1.0,
1128 "rotation_matrix[" + std::to_string(i) +
"][" + std::to_string(j) +
1129 "] is larger than one: " + std::to_string(rotation_matrix[i][j]) +
". rotation_matrix = \n" 1130 + std::to_string(rotation_matrix[0][0]) +
" " + std::to_string(rotation_matrix[0][1]) +
" " + std::to_string(rotation_matrix[0][2]) +
"\n" 1131 + std::to_string(rotation_matrix[1][0]) +
" " + std::to_string(rotation_matrix[1][1]) +
" " + std::to_string(rotation_matrix[1][2]) +
"\n" 1132 + std::to_string(rotation_matrix[2][0]) +
" " + std::to_string(rotation_matrix[2][1]) +
" " + std::to_string(rotation_matrix[2][2]));
1135 const double theta = std::acos(rotation_matrix[2][2]);
1136 const double phi1 = std::atan2(rotation_matrix[2][0]/-
sin(theta),rotation_matrix[2][1]/-
sin(theta));
1137 const double phi2 = std::atan2(rotation_matrix[0][2]/-
sin(theta),rotation_matrix[1][2]/
sin(theta));
1139 euler_angles[0] =
wrap_angle(phi1 * rad_to_degree);
1140 euler_angles[1] =
wrap_angle(theta * rad_to_degree);
1141 euler_angles[2] =
wrap_angle(phi2 * rad_to_degree);
1143 return euler_angles;
1146 std::array<std::array<double,3>,3>
1150 const double degree_to_rad =
Consts::PI/180.0;
1151 const double phi1 = phi1_d * degree_to_rad;
1152 const double theta = theta_d * degree_to_rad;
1153 const double phi2 = phi2_d * degree_to_rad;
1154 std::array<std::array<double,3>,3> rot_matrix;
1157 rot_matrix[0][0] =
cos(phi2)*
cos(phi1) -
cos(theta)*
sin(phi1)*
sin(phi2);
1158 rot_matrix[0][1] = -
cos(phi2)*
sin(phi1) -
cos(theta)*
cos(phi1)*
sin(phi2);
1159 rot_matrix[0][2] = -
sin(phi2)*
sin(theta);
1161 rot_matrix[1][0] =
sin(phi2)*
cos(phi1) +
cos(theta)*
sin(phi1)*
cos(phi2);
1162 rot_matrix[1][1] = -
sin(phi2)*
sin(phi1) +
cos(theta)*
cos(phi1)*
cos(phi2);
1163 rot_matrix[1][2] =
cos(phi2)*
sin(theta);
1165 rot_matrix[2][0] = -
sin(theta)*
sin(phi1);
1166 rot_matrix[2][1] = -
sin(theta)*
cos(phi1);
1167 rot_matrix[2][2] =
cos(theta);
1174 std::string data_string;
1177 int mpi_initialized;
1178 MPI_Initialized(&mpi_initialized);
1179 if (mpi_initialized != 0)
1181 const MPI_Comm comm = MPI_COMM_WORLD;
1183 MPI_Comm_rank(comm, &my_rank);
1187 std::ifstream filestream;
1188 filestream.open(filename.c_str());
1189 WBAssertThrow (filestream.is_open(), std::string(
"Could not open file <") + filename +
">.");
1193 int invalid_file_size = -1;
1198 const int ierr = MPI_Bcast(&invalid_file_size, 1, MPI_INT, 0, comm);
1200 std::string(
"Could not open file <") + filename +
">.");
1204 std::stringstream datastream;
1208 datastream << filestream.rdbuf();
1210 catch (
const std::ios::failure &)
1213 const int ierr = MPI_Bcast(&invalid_file_size, 1, MPI_INT, 0, comm);
1216 std::string(
"Could not read file content from <") + filename +
">.");
1219 data_string = datastream.str();
1220 WBAssertThrow(static_cast<long int>(data_string.size()) < std::numeric_limits<int>::max(),
1221 "File is too large to be send with MPI.");
1222 filesize =
static_cast<int>(data_string.size());
1225 int ierr = MPI_Bcast(&filesize, 1, MPI_INT, 0, comm);
1229 ierr = MPI_Bcast(&data_string[0],
1240 int ierr = MPI_Bcast(&filesize, 1, MPI_INT, 0, comm);
1243 std::string(
"Could not open file <") + filename +
">.");
1245 data_string.resize(static_cast<size_t>(filesize));
1248 ierr = MPI_Bcast(&data_string[0],
1258 std::ifstream filestream;
1259 filestream.open(filename.c_str());
1263 std::string(
"Could not open file <") + filename +
">.");
1265 std::stringstream datastream;
1266 datastream << filestream.rdbuf();
1267 data_string = datastream.str();
1270 std::ifstream filestream;
1271 filestream.open(filename.c_str());
1275 std::string(
"Could not open file <") + filename +
">.");
1277 std::stringstream datastream;
1278 datastream << filestream.rdbuf();
1279 data_string = datastream.str();
1291 std::vector<std::vector<double>> mid_oceanic_spreading_velocities,
1292 const std::unique_ptr<WorldBuilder::CoordinateSystems::Interface> &coordinate_system,
1294 const std::vector<std::vector<double>> &subducting_plate_velocities,
1295 const std::vector<double> &ridge_migration_times)
1297 const double seconds_in_year = 60.0 * 60.0 * 24.0 * 365.25;
1299 double distance_ridge = std::numeric_limits<double>::max();
1300 double spreading_velocity_at_ridge = 0;
1301 double subducting_velocity_at_trench = 0;
1302 double ridge_migration_time = 0;
1305 unsigned int relevant_ridge = 0;
1309 Point<2> other_check_point = check_point;
1314 if (mid_oceanic_ridges[0].size() > 1)
1318 for (relevant_ridge = 0; relevant_ridge < mid_oceanic_ridges.size()-1; relevant_ridge++)
1320 const Point<2> transform_point_0 = mid_oceanic_ridges[relevant_ridge+1][0];
1321 const Point<2> transform_point_1 = mid_oceanic_ridges[relevant_ridge][mid_oceanic_ridges[relevant_ridge].size()-1];
1322 const Point<2> reference_point = mid_oceanic_ridges[relevant_ridge][0];
1323 const bool reference_on_side_of_line = (transform_point_1[0] - transform_point_0[0])
1324 * (reference_point[1] - transform_point_0[1])
1325 - (transform_point_1[1] - transform_point_0[1])
1326 * (reference_point[0] - transform_point_0[0])
1328 const bool checkpoint_on_side_of_line = (transform_point_1[0] - transform_point_0[0])
1329 * (check_point[1] - transform_point_0[1])
1330 - (transform_point_1[1] - transform_point_0[1])
1331 * (check_point[0] - transform_point_0[0])
1335 if (reference_on_side_of_line == checkpoint_on_side_of_line)
1343 for (
unsigned int i_coordinate = 0; i_coordinate < mid_oceanic_ridges[relevant_ridge].size() - 1; i_coordinate++)
1345 const Point<2> segment_point0 = mid_oceanic_ridges[relevant_ridge][i_coordinate];
1346 const Point<2> segment_point1 = mid_oceanic_ridges[relevant_ridge][i_coordinate + 1];
1348 const double spreading_velocity_point0 = mid_oceanic_spreading_velocities[relevant_ridge][i_coordinate];
1349 const double spreading_velocity_point1 = mid_oceanic_spreading_velocities[relevant_ridge][i_coordinate + 1];
1355 double subducting_velocity_point0 = subducting_plate_velocities[0][0];
1356 double subducting_velocity_point1 = subducting_plate_velocities[0][0];
1359 if (subducting_plate_velocities[0].size() > 1)
1361 WBAssert(subducting_plate_velocities.size() == mid_oceanic_ridges.size() && \
1362 subducting_plate_velocities[relevant_ridge].size() == mid_oceanic_ridges[relevant_ridge].size(),
1363 "subducting velocity and ridge coordinates must be the same dimension");
1364 WBAssert(ridge_migration_times.size() == mid_oceanic_ridges.size(),
1365 "the times for ridge migration specified in 'spreading velocity' must be the same dimension " 1366 "as ridge coordinates.");
1367 subducting_velocity_point0 = subducting_plate_velocities[relevant_ridge][i_coordinate];
1368 subducting_velocity_point1 = subducting_plate_velocities[relevant_ridge][i_coordinate + 1];
1369 ridge_migration_time = ridge_migration_times[relevant_ridge];
1374 const Point<2> v = segment_point1 - segment_point0;
1375 const Point<2> w1 = check_point - segment_point0;
1376 const Point<2> w2 = other_check_point - segment_point0;
1378 const double c1 = (w1[0] * v[0] + w1[1] * v[1]);
1379 const double c = (v[0] * v[0] + v[1] * v[1]);
1380 const double c2 = (w2[0] * v[0] + w2[1] * v[1]);
1383 Point<2> Pb1(coordinate_system->natural_coordinate_system());
1388 double spreading_velocity_at_ridge_pt1 = 0.0;
1389 double subducting_velocity_at_trench_pt1 = 0.0;
1390 double spreading_velocity_at_ridge_pt2 = 0.0;
1391 double subducting_velocity_at_trench_pt2 = 0.0;
1396 spreading_velocity_at_ridge_pt1 = spreading_velocity_point0;
1397 subducting_velocity_at_trench_pt1 = subducting_velocity_point0;
1402 spreading_velocity_at_ridge_pt1 = spreading_velocity_point1;
1403 subducting_velocity_at_trench_pt1 = subducting_velocity_point1;
1407 Pb1=segment_point0 + (c1 / c) * v;
1408 spreading_velocity_at_ridge_pt1 = spreading_velocity_point0 + (spreading_velocity_point1 - spreading_velocity_point0) * (c1 / c);
1409 subducting_velocity_at_trench_pt1 = subducting_velocity_point0 + (subducting_velocity_point1 - subducting_velocity_point0) * (c1 / c);
1412 Point<2> Pb2(coordinate_system->natural_coordinate_system());
1416 spreading_velocity_at_ridge_pt2 = spreading_velocity_point0;
1417 subducting_velocity_at_trench_pt2 = subducting_velocity_point0;
1422 spreading_velocity_at_ridge_pt2 = spreading_velocity_point1;
1423 subducting_velocity_at_trench_pt2 = spreading_velocity_point1;
1427 Pb2=segment_point0 + (c2 / c) * v;
1428 spreading_velocity_at_ridge_pt2 = spreading_velocity_point0 + (spreading_velocity_point1 - spreading_velocity_point0) * (c2 / c);
1429 subducting_velocity_at_trench_pt2 = subducting_velocity_point0 + (subducting_velocity_point1 - subducting_velocity_point0) * (c2 / c);
1432 Point<3> compare_point1(coordinate_system->natural_coordinate_system());
1433 Point<3> compare_point2(coordinate_system->natural_coordinate_system());
1435 compare_point1[0] = coordinate_system->natural_coordinate_system() ==
cartesian ? Pb1[0] : position_in_natural_coordinates_at_min_depth.
get_depth_coordinate();
1436 compare_point1[1] = coordinate_system->natural_coordinate_system() ==
cartesian ? Pb1[1] : Pb1[0];
1437 compare_point1[2] = coordinate_system->natural_coordinate_system() ==
cartesian ? position_in_natural_coordinates_at_min_depth.
get_depth_coordinate() : Pb1[1];
1439 compare_point2[0] = coordinate_system->natural_coordinate_system() ==
cartesian ? Pb2[0] : position_in_natural_coordinates_at_min_depth.
get_depth_coordinate();
1440 compare_point2[1] = coordinate_system->natural_coordinate_system() ==
cartesian ? Pb2[1] : Pb2[0];
1441 compare_point2[2] = coordinate_system->natural_coordinate_system() ==
cartesian ? position_in_natural_coordinates_at_min_depth.
get_depth_coordinate() : Pb2[1];
1443 const double compare_distance1 = coordinate_system->distance_between_points_at_same_depth(
Point<3>(position_in_natural_coordinates_at_min_depth.
get_coordinates(),
1447 const double compare_distance2 = coordinate_system->distance_between_points_at_same_depth(
Point<3>(position_in_natural_coordinates_at_min_depth.
get_coordinates(),
1451 double compare_distance = compare_distance1;
1452 double spreading_velocity_at_ridge_pt = spreading_velocity_at_ridge_pt1;
1453 double subducting_velocity_at_trench_pt = subducting_velocity_at_trench_pt1;
1457 if (compare_distance2 < compare_distance1)
1459 compare_distance = compare_distance2;
1460 spreading_velocity_at_ridge_pt = spreading_velocity_at_ridge_pt2;
1461 subducting_velocity_at_trench_pt = subducting_velocity_at_trench_pt2;
1465 if (i_coordinate == 0 || compare_distance < distance_ridge)
1467 distance_ridge = compare_distance;
1468 spreading_velocity_at_ridge = spreading_velocity_at_ridge_pt;
1469 subducting_velocity_at_trench = subducting_velocity_at_trench_pt;
1473 std::vector<double> result;
1474 result.push_back(spreading_velocity_at_ridge / seconds_in_year);
1475 result.push_back(distance_ridge);
1476 result.push_back(subducting_velocity_at_trench / seconds_in_year);
1477 result.push_back(ridge_migration_time);
1485 WBAssert(ridge_parameters.size() == 4,
"Internal error: ridge_parameters have the wrong size: " << ridge_parameters.size() <<
" instead of 4.");
1486 const double seconds_in_year = 60.0 * 60.0 * 24.0 * 365.25;
1487 const double spreading_velocity = ridge_parameters[0] * seconds_in_year;
1488 const double distance_ridge = ridge_parameters[1];
1489 const double subducting_velocity = ridge_parameters[2] * seconds_in_year;
1491 WBAssertThrow(subducting_velocity >= 0,
"The subducting velocity is less than 0. " 1492 "Subducting velocity: " << subducting_velocity);
1495 double effective_plate_age = (distance_ridge + distance_along_plane) / spreading_velocity;
1498 const double age_at_trench = effective_plate_age - distance_along_plane / subducting_velocity;
1499 WBAssertThrow(age_at_trench >= 0,
"The age of trench at subducting initiation is less than 0. " 1500 "Age at trench: " << age_at_trench);
1502 std::vector<double> result;
1503 result.push_back(age_at_trench);
1504 result.push_back(effective_plate_age);
1509 std::array<std::array<double,3>,3>
1512 std::array<std::array<double,3>,3> result;
1513 for (
size_t i = 0; i < 3; i++)
1515 for (
size_t j = 0; j < 3; j++)
1518 for (
size_t k = 0; k < 3; k++)
1520 result[i][j] += mat1[i][k] * mat2[k][j];
bool polygon_contains_point_implementation(const std::vector< Point< 2 > > &point_list, const Point< 2 > &point)
std::array< double, dim > convert_point_to_array(const Point< dim > &point_)
Class for circle line/spline, including interpolation on it.
std::array< double, 3 > cartesian_to_spherical_coordinates(const Point< 3 > &position)
std::vector< std::array< double, 4 > > m
template std::array< double, 2 > convert_point_to_array< 2 >(const Point< 2 > &point_)
std::array< double, 2 > get_surface_coordinates() const
double get_depth_coordinate() const
bool approx(double a, double b, double error_factor=1e4)
std::array< std::array< double, 3 >, 3 > multiply_3x3_matrices(const std::array< std::array< double, 3 >, 3 > mat1, const std::array< std::array< double, 3 >, 3 > mat2)
double parametric_fraction
int string_to_int(const std::string &string)
Point< 3 > spherical_to_cartesian_coordinates(const std::array< double, 3 > &scoord)
double distance(const Point< 2 > &two) const
CoordinateSystem get_coordinate_system() const
const std::array< double, dim > & get_array() const
Point< 3 > cross_product(const Point< 3 > &a, const Point< 3 > &b)
template std::array< double, 3 > convert_point_to_array< 3 >(const Point< 3 > &point_)
std::string read_and_distribute_file_content(const std::string &filename)
CoordinateSystem get_coordinate_system() const
std::vector< double > calculate_ridge_distance_and_spreading(std::vector< std::vector< Point< 2 >>> mid_oceanic_ridges, std::vector< std::vector< double >> mid_oceanic_spreading_velocities, const std::unique_ptr< WorldBuilder::CoordinateSystems::Interface > &coordinate_system, const Objects::NaturalCoordinate &position_in_natural_coordinates_at_min_depth, const std::vector< std::vector< double >> &subducting_plate_velocities, const std::vector< double > &ridge_migration_times)
#define WBAssert(condition, message)
double cos(const double angle)
double distance_from_plane
void set_points(const std::vector< double > &y)
ClosestPointOnCurve closest_point_on_curve_segment(const Point< 2 > &p, const bool verbose=false) const
Finds the closest point on the curve. If the the closest point doesn't fall on the segment...
PointDistanceFromCurvedPlanes distance_point_from_curved_planes(const Point< 3 > &check_point, const Objects::NaturalCoordinate &natural_coordinate, const Point< 2 > &reference_point, const std::vector< Point< 2 > > &point_list, const std::vector< std::vector< double > > &plane_segment_lengths, const std::vector< std::vector< Point< 2 > > > &plane_segment_angles, const double start_radius, const std::unique_ptr< CoordinateSystems::Interface > &coordinate_system, const bool only_positive, const Objects::BezierCurve &bezier_curve)
double wrap_angle(const double angle)
#define WBAssertThrow(condition, message)
double string_to_double(const std::string &string)
unsigned int string_to_unsigned_int(const std::string &string)
std::vector< double > calculate_effective_trench_and_plate_ages(std::vector< double > ridge_parameters, double distance_along_plane)
double fraction_from_ellipse_center(const Point< 2 > &ellipse_center, const double semi_major_axis, const double eccentricity, const double theta, const Point< 2 > &point)
std::array< std::array< double, 3 >, 3 > euler_angles_to_rotation_matrix(double phi1_d, double theta_d, double phi2_d)
double sin(const double raw_angle)
bool polygon_contains_point(const std::vector< Point< 2 > > &point_list, const Point< 2 > &point)
std::array< double, 3 > euler_angles_from_rotation_matrix(const std::array< std::array< double, 3 >, 3 > &rotation_matrix)
CoordinateSystem string_to_coordinate_system(const std::string &coordinate_system)
double signed_distance_to_polygon(const std::vector< Point< 2 > > &point_list, const Point< 2 > &point)
double interpolate_angle_across_zero(const double angle_1, const double angle_2, const double fraction)
const std::array< double, 3 > & get_coordinates() const