mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-18 19:30:25 +00:00
Implements business to geometry mapping for alignment cant.
Also fixes problems that were created by this work in other files
This commit is contained in:
@@ -448,14 +448,17 @@ class curve_segment_evaluator {
|
||||
|
||||
// defines the parent_curve_fn_ functor for cant segments.
|
||||
void set_cant_spiral_function(std::function<double(double)> Superelevation, std::function<double(double)> SuperelevationSlope, std::function<double(double)> Cant) {
|
||||
auto dy = (*curve_segment_placement_)(1, 2); // placement dy
|
||||
auto dz = (*curve_segment_placement_)(2, 2); // placement dz
|
||||
// compute start cross slope angle, measured relative to (0,0,1)
|
||||
auto dy = (*curve_segment_placement_)(1, 2); // Axis.dy
|
||||
auto dz = (*curve_segment_placement_)(2, 2); // Axis.dz
|
||||
auto start_angle = atan2(dz, dy);
|
||||
|
||||
// compute end cross slope angle, measured relative to (0,0,1)
|
||||
dy = (next_segment_placement_.has_value() ? (*next_segment_placement_)(1, 2) : 0.0);
|
||||
dz = (next_segment_placement_.has_value() ? (*next_segment_placement_)(2, 2) : 1.0);
|
||||
auto end_angle = atan2(dz, dy);
|
||||
|
||||
// angular change of railhead cross slope over the length of the segment
|
||||
auto delta_angle = end_angle - start_angle;
|
||||
auto start_cant = Cant(0.0 /*start_*/);
|
||||
auto end_cant = Cant(/* start_ + */ length_);
|
||||
@@ -529,7 +532,7 @@ class curve_segment_evaluator {
|
||||
if (segment_type_ == ST_CANT) {
|
||||
boost::optional<std::function<double(double)>> super, slope;
|
||||
std::tie(super, slope) = get_superelevation_functions();
|
||||
auto cant = [A, L](double t) -> double { return A ? L * A * t / fabs(pow(A, 3)) : 0.0; };
|
||||
auto cant = [A, L](double t) -> double { return A ? L * L * A * t / fabs(pow(A, 3)) : 0.0; };
|
||||
|
||||
if (!super.has_value()) {
|
||||
super = cant;
|
||||
@@ -579,9 +582,9 @@ class curve_segment_evaluator {
|
||||
std::tie(super, slope) = get_superelevation_functions();
|
||||
|
||||
auto cant = [constant_term, cosine_term, L](double t) -> double {
|
||||
auto a0 = constant_term.has_value() ? L / constant_term.value() : 0.0;
|
||||
auto a1 = (L / cosine_term) * cos(PI * t / L);
|
||||
return a0 + a1;
|
||||
auto a0 = constant_term.has_value() ? 1 / constant_term.value() : 0.0;
|
||||
auto a1 = (1 / cosine_term) * cos(PI * t / L);
|
||||
return L*L*(a0 + a1);
|
||||
};
|
||||
|
||||
if (!super.has_value()) {
|
||||
@@ -627,7 +630,7 @@ class curve_segment_evaluator {
|
||||
if (segment_type_ == ST_HORIZONTAL) {
|
||||
auto theta = [constant_term, linear_term, sine_term, L](double t) -> double {
|
||||
auto a0 = constant_term.has_value() ? t / constant_term.value() : 0.0;
|
||||
auto a1 = linear_term.has_value() ? sign(linear_term.value()) * pow(t / linear_term.value(), 2.0) / 2.0 : 0.0;
|
||||
auto a1 = linear_term.has_value() ? (linear_term.value() / fabs(linear_term.value())) * pow(t / linear_term.value(), 2.0) / 2.0 : 0.0;
|
||||
auto a2 = -1.0 * (L / (2 * PI * sine_term)) * (cos(2 * PI * t / L) - 1.0);
|
||||
return a0 + a1 + a2;
|
||||
};
|
||||
@@ -635,7 +638,7 @@ class curve_segment_evaluator {
|
||||
auto fn_y = [theta](double t) -> double { return sin(theta(t)); };
|
||||
auto curvature = [constant_term, linear_term, sine_term, L](double t) -> double {
|
||||
auto a0 = constant_term.has_value() ? L / constant_term.value() : 0.0;
|
||||
auto a1 = linear_term.has_value() ? sign(linear_term.value()) * pow(L / linear_term.value(), 2.0)*(t/L) : 0.0;
|
||||
auto a1 = linear_term.has_value() ? (linear_term.value() / fabs(linear_term.value())) * pow(L / linear_term.value(), 2.0) * (t / L) : 0.0;
|
||||
auto a2 = (L / sine_term) * sin(2 * PI * t / L);
|
||||
return a0 + a1 + a2;
|
||||
};
|
||||
@@ -646,10 +649,10 @@ class curve_segment_evaluator {
|
||||
std::tie(super, slope) = get_superelevation_functions();
|
||||
|
||||
auto cant = [constant_term, linear_term, sine_term, L](double t) -> double {
|
||||
auto a0 = constant_term.has_value() ? L / constant_term.value() : 0.0;
|
||||
auto a1 = linear_term.has_value() ? sign(linear_term.value()) * pow(L / linear_term.value(), 2.0) * (t / L) : 0.0;
|
||||
auto a2 = (L / sine_term) * sin(2 * PI * t / L);
|
||||
return a0 + a1 + a2;
|
||||
auto a0 = constant_term.has_value() ? 1 / constant_term.value() : 0.0;
|
||||
auto a1 = linear_term.has_value() ? (linear_term.value()/fabs(linear_term.value())) * pow(1 / linear_term.value(), 2.0) * t : 0.0;
|
||||
auto a2 = (1 / sine_term) * sin(2 * PI * t / L);
|
||||
return L*L*(a0 + a1 + a2);
|
||||
};
|
||||
|
||||
if (!super.has_value()) {
|
||||
@@ -681,14 +684,14 @@ class curve_segment_evaluator {
|
||||
|
||||
void polynomial_spiral(boost::optional<double> A0, boost::optional<double> A1, boost::optional<double> A2, boost::optional<double> A3, boost::optional<double> A4, boost::optional<double> A5, boost::optional<double> A6, boost::optional<double> A7) {
|
||||
auto theta = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_ * length_unit_, lu = length_unit_](double t) -> double {
|
||||
auto a0 = A0.has_value() ? t / (A0.value() * lu) : 0.0;
|
||||
auto a1 = A1.has_value() ? A1.value() * lu * std::pow(t, 2) / (2 * fabs(std::pow(A1.value() * lu, 3))) : 0.0;
|
||||
auto a2 = A2.has_value() ? std::pow(t, 3) / (3 * std::pow(A2.value() * lu, 3)) : 0.0;
|
||||
auto a3 = A3.has_value() ? A3.value() * lu * std::pow(t, 4) / (4 * fabs(std::pow(A3.value() * lu, 5))) : 0.0;
|
||||
auto a4 = A4.has_value() ? std::pow(t, 5) / (5 * std::pow(A4.value() * lu, 5)) : 0.0;
|
||||
auto a5 = A5.has_value() ? A5.value() * lu * std::pow(t, 6) / (6 * fabs(std::pow(A5.value() * lu, 7))) : 0.0;
|
||||
auto a6 = A6.has_value() ? std::pow(t, 7) / (7 * std::pow(A6.value() * lu, 7)) : 0.0;
|
||||
auto a7 = A7.has_value() ? A7.value() * lu * std::pow(t, 8) / (8 * fabs(std::pow(A7.value() * lu, 9))) : 0.0;
|
||||
auto a0 = A0.get_value_or(0.0) != 0.0 ? t / (A0.value() * lu) : 0.0;
|
||||
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * std::pow(t, 2) / (2 * fabs(std::pow(A1.value() * lu, 3))) : 0.0;
|
||||
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 3) / (3 * std::pow(A2.value() * lu, 3)) : 0.0;
|
||||
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 4) / (4 * fabs(std::pow(A3.value() * lu, 5))) : 0.0;
|
||||
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 5) / (5 * std::pow(A4.value() * lu, 5)) : 0.0;
|
||||
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 6) / (6 * fabs(std::pow(A5.value() * lu, 7))) : 0.0;
|
||||
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 7) / (7 * std::pow(A6.value() * lu, 7)) : 0.0;
|
||||
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 8) / (8 * fabs(std::pow(A7.value() * lu, 9))) : 0.0;
|
||||
return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7;
|
||||
};
|
||||
|
||||
@@ -699,14 +702,14 @@ class curve_segment_evaluator {
|
||||
// this is same as cant function in polynomial_cant_spiral
|
||||
auto curvature = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
|
||||
t += start;
|
||||
auto a0 = A0.has_value() ? 1 / (A0.value() * lu) : 0.0;
|
||||
auto a1 = A1.has_value() ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
|
||||
auto a2 = A2.has_value() ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
|
||||
auto a3 = A3.has_value() ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
|
||||
auto a4 = A4.has_value() ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
|
||||
auto a5 = A5.has_value() ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
|
||||
auto a6 = A6.has_value() ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
|
||||
auto a7 = A7.has_value() ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
|
||||
auto a0 = A0.get_value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
|
||||
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
|
||||
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
|
||||
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
|
||||
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
|
||||
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
|
||||
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
|
||||
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
|
||||
return L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
|
||||
};
|
||||
|
||||
@@ -721,15 +724,15 @@ class curve_segment_evaluator {
|
||||
|
||||
auto cant = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
|
||||
t += start;
|
||||
auto a0 = A0.has_value() ? 1 / (A0.value() * lu) : 0.0;
|
||||
auto a1 = A1.has_value() ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
|
||||
auto a2 = A2.has_value() ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
|
||||
auto a3 = A3.has_value() ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
|
||||
auto a4 = A4.has_value() ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
|
||||
auto a5 = A5.has_value() ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
|
||||
auto a6 = A6.has_value() ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
|
||||
auto a7 = A7.has_value() ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
|
||||
return L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
|
||||
auto a0 = A0.get_value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
|
||||
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
|
||||
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
|
||||
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
|
||||
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
|
||||
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
|
||||
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
|
||||
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
|
||||
return L * L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
|
||||
};
|
||||
|
||||
if (!super.has_value()) {
|
||||
@@ -739,14 +742,14 @@ class curve_segment_evaluator {
|
||||
if (!slope.has_value()) {
|
||||
slope = [A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
|
||||
t += start;
|
||||
auto a1 = A1.has_value() ? A1.value() * lu / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
|
||||
auto a2 = A2.has_value() ? 2 * t / std::pow(A2.value() * lu, 3) : 0.0;
|
||||
auto a3 = A3.has_value() ? 3 * A3.value() * lu * std::pow(t, 2) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
|
||||
auto a4 = A4.has_value() ? 4 * std::pow(t, 3) / std::pow(A4.value() * lu, 5) : 0.0;
|
||||
auto a5 = A5.has_value() ? 5 * A5.value() * lu * std::pow(t, 4) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
|
||||
auto a6 = A6.has_value() ? 6 * std::pow(t, 5) / std::pow(A6.value() * lu, 7) : 0.0;
|
||||
auto a7 = A7.has_value() ? 7 * A7.value() * lu * std::pow(t, 6) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
|
||||
return L * (a1 + a2 + a3 + a4 + a5 + a6 + a7);
|
||||
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
|
||||
auto a2 = A2.get_value_or(0.0) != 0.0 ? 2 * t / std::pow(A2.value() * lu, 3) : 0.0;
|
||||
auto a3 = A3.get_value_or(0.0) != 0.0 ? 3 * A3.value() * lu * std::pow(t, 2) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
|
||||
auto a4 = A4.get_value_or(0.0) != 0.0 ? 4 * std::pow(t, 3) / std::pow(A4.value() * lu, 5) : 0.0;
|
||||
auto a5 = A5.get_value_or(0.0) != 0.0 ? 5 * A5.value() * lu * std::pow(t, 4) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
|
||||
auto a6 = A6.get_value_or(0.0) != 0.0 ? 6 * std::pow(t, 5) / std::pow(A6.value() * lu, 7) : 0.0;
|
||||
auto a7 = A7.get_value_or(0.0) != 0.0 ? 7 * A7.value() * lu * std::pow(t, 6) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
|
||||
return L * L * (a1 + a2 + a3 + a4 + a5 + a6 + a7);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user