feat(cpp-object-oriented-modular-refactoring): step 9 - result-io-vector3
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/math/vector3.h"
|
||||
#include "fesa/model/shell_geometry.h"
|
||||
|
||||
namespace fesa {
|
||||
@@ -1800,61 +1801,41 @@ class MappingContext {
|
||||
|
||||
bool ValidateGeometry(const RawElement& raw, const Node& first,
|
||||
const Node& second, const GeneralBeamSection& section) {
|
||||
const auto norm = [](const std::array<double, 3>& vector) {
|
||||
return std::hypot(vector[0], vector[1], vector[2]);
|
||||
};
|
||||
const auto maximum_absolute = [](const std::array<double, 3>& vector) {
|
||||
const auto maximum_absolute = [](const Vector3& vector) {
|
||||
return std::max(
|
||||
{std::abs(vector[0]), std::abs(vector[1]), std::abs(vector[2])});
|
||||
};
|
||||
const Vector3 first_position{first.coordinates};
|
||||
const Vector3 second_position{second.coordinates};
|
||||
|
||||
// Compare both approved inequalities after a common scaling. This
|
||||
// preserves the exact ratios while avoiding overflow in x*x and in
|
||||
// subtraction between large finite coordinates.
|
||||
const double global_coordinate_scale =
|
||||
std::max({1.0, maximum_absolute(first.coordinates),
|
||||
maximum_absolute(second.coordinates)});
|
||||
std::array<double, 3> first_scaled{};
|
||||
std::array<double, 3> second_scaled{};
|
||||
std::array<double, 3> delta_scaled{};
|
||||
for (std::size_t coordinate = 0U; coordinate < 3U; ++coordinate) {
|
||||
first_scaled[coordinate] =
|
||||
first.coordinates[coordinate] / global_coordinate_scale;
|
||||
second_scaled[coordinate] =
|
||||
second.coordinates[coordinate] / global_coordinate_scale;
|
||||
delta_scaled[coordinate] =
|
||||
second_scaled[coordinate] - first_scaled[coordinate];
|
||||
}
|
||||
const double length_ratio = norm(delta_scaled);
|
||||
std::max({1.0, maximum_absolute(first_position),
|
||||
maximum_absolute(second_position)});
|
||||
const Vector3 first_scaled = first_position / global_coordinate_scale;
|
||||
const Vector3 second_scaled = second_position / global_coordinate_scale;
|
||||
const Vector3 delta_scaled = second_scaled - first_scaled;
|
||||
const double length_ratio = delta_scaled.Norm();
|
||||
const double coordinate_norm_ratio =
|
||||
std::max({1.0 / global_coordinate_scale, norm(first_scaled),
|
||||
norm(second_scaled)});
|
||||
std::max({1.0 / global_coordinate_scale, first_scaled.Norm(),
|
||||
second_scaled.Norm()});
|
||||
if (!(length_ratio > 1.0e-12 * coordinate_norm_ratio)) {
|
||||
return ModelFailure(
|
||||
"invalid-beam-length", raw.location, "ELEMENT", raw.label_text,
|
||||
"Beam length fails the approved scale-aware threshold.");
|
||||
}
|
||||
std::array<double, 3> tangent{delta_scaled[0] / length_ratio,
|
||||
delta_scaled[1] / length_ratio,
|
||||
delta_scaled[2] / length_ratio};
|
||||
const Vector3 tangent = delta_scaled / length_ratio;
|
||||
|
||||
const double global_guide_scale =
|
||||
std::max(1.0, maximum_absolute(section.first_axis));
|
||||
std::array<double, 3> guide_scaled{};
|
||||
for (std::size_t coordinate = 0U; coordinate < 3U; ++coordinate) {
|
||||
guide_scaled[coordinate] =
|
||||
section.first_axis[coordinate] / global_guide_scale;
|
||||
}
|
||||
const double projection = guide_scaled[0] * tangent[0] +
|
||||
guide_scaled[1] * tangent[1] +
|
||||
guide_scaled[2] * tangent[2];
|
||||
std::array<double, 3> perpendicular{
|
||||
guide_scaled[0] - projection * tangent[0],
|
||||
guide_scaled[1] - projection * tangent[1],
|
||||
guide_scaled[2] - projection * tangent[2]};
|
||||
const Vector3 guide{section.first_axis};
|
||||
const double global_guide_scale = std::max(1.0, maximum_absolute(guide));
|
||||
const Vector3 guide_scaled = guide / global_guide_scale;
|
||||
const double projection = guide_scaled.Dot(tangent);
|
||||
const Vector3 perpendicular = guide_scaled - projection * tangent;
|
||||
const double guide_norm_ratio =
|
||||
std::max(1.0 / global_guide_scale, norm(guide_scaled));
|
||||
if (!(norm(perpendicular) > 1.0e-12 * guide_norm_ratio)) {
|
||||
std::max(1.0 / global_guide_scale, guide_scaled.Norm());
|
||||
if (!(perpendicular.Norm() > 1.0e-12 * guide_norm_ratio)) {
|
||||
return ModelFailure(
|
||||
"invalid-beam-guide-vector", section.location, "BEAM GENERAL SECTION",
|
||||
raw.label_text,
|
||||
|
||||
Reference in New Issue
Block a user