18 const std::vector<std::shared_ptr<SymbolicExpr>>& p1,
19 const std::vector<std::shared_ptr<SymbolicExpr>>&
p2,
21 const std::string& operation,
22 std::vector<double>& p1_values,
23 std::vector<double>& p2_values)
26 p1,
context, operation, &p1_values);
39 if (!p1_scale || !p2_scale) {
42 const double scale = std::max(p1_scale.value(), p2_scale.value());
43 for (
size_t i = 0; i < 3; ++i) {
44 if (!std::isfinite(p2_values[i] - p1_values[i])) {
52 const std::vector<std::shared_ptr<SymbolicExpr>>& direction1,
53 const std::vector<std::shared_ptr<SymbolicExpr>>& direction2,
54 const std::vector<std::shared_ptr<SymbolicExpr>>& difference,
57 const std::string& operation)
62 cross.value(),
context, operation,
63 "skew line distance requires non-parallel directions",
64 "cross-product nonzero condition cannot be verified");
69 cross.value(), cross.value(),
context);
73 auto cross_norm = SymbolicExpr::sqrt(cross_norm_sq.value());
79 std::vector<std::shared_ptr<const SymbolicNode>>{
81 auto distance = SymbolicExpr::divide(abs_num, cross_norm);
82 if (point_scale != 0.0) {
83 distance = SymbolicExpr::multiply(
84 distance, SymbolicExpr::number(point_scale));
88 "skew line distance is outside the supported domain",
context);
98 const std::string operation =
"skew_lines_distance";
108 auto step =
context.consume_steps(8, operation);
113 std::vector<double> direction1_values;
114 std::vector<double> direction2_values;
121 l2.direction,
context, operation, &direction2_values);
126 std::vector<std::shared_ptr<SymbolicExpr>> direction1;
127 std::vector<std::shared_ptr<SymbolicExpr>> direction2;
128 direction1.reserve(3);
129 direction2.reserve(3);
130 for (
size_t i = 0; i < 3; ++i) {
131 direction1.push_back(SymbolicExpr::number(
132 direction1_values[i] / scale1.value()));
133 direction2.push_back(SymbolicExpr::number(
134 direction2_values[i] / scale2.value()));
137 std::vector<double> point1_values;
138 std::vector<double> point2_values;
139 auto difference_scale = point_difference_scale_checked(
140 l1.
point,
l2.point,
context, operation, point1_values, point2_values);
141 if (!difference_scale) {
144 const double point_scale = difference_scale.value();
146 std::vector<std::shared_ptr<SymbolicExpr>> a2_minus_a1;
147 a2_minus_a1.reserve(3);
148 for (
size_t i = 0; i < l1.
point.size(); ++i) {
149 if (point_scale != 0.0) {
150 a2_minus_a1.push_back(SymbolicExpr::number(
151 point2_values[i] / point_scale -
152 point1_values[i] / point_scale));
155 a2_minus_a1.push_back(SymbolicExpr::add(
157 SymbolicExpr::multiply(
158 SymbolicExpr::number(-1), l1.
point[i])));
160 return skew_distance_from_directions(
161 direction1, direction2, a2_minus_a1, point_scale,
context, operation);
162 }
catch (
const std::bad_alloc&) {
164 "vector geometry allocation failed",
166 }
catch (
const std::exception&
e) {
168 e.what(), operation);
182 const std::vector<std::shared_ptr<SymbolicExpr>>& p1,
183 const std::vector<std::shared_ptr<SymbolicExpr>>&
p2,
185 const std::string operation =
"line_from_two_points";
189 if (p1.size() != 3) {
192 "line construction requires 3-dimensional points",
195 auto step =
context.consume_steps(4, operation);
198 std::vector<double> p1_values;
199 std::vector<double> p2_values;
200 auto difference_scale = point_difference_scale_checked(
201 p1,
p2,
context, operation, p1_values, p2_values);
202 if (!difference_scale) {
205 const double point_scale = difference_scale.value();
210 for (
size_t i = 0; i < p1.size(); ++i) {
211 if (point_scale != 0.0) {
212 line.
direction.push_back(SymbolicExpr::number(
213 p2_values[i] / point_scale -
214 p1_values[i] / point_scale));
217 auto component = SymbolicExpr::add(
219 SymbolicExpr::multiply(SymbolicExpr::number(-1), p1[i]));
221 component, operation,
222 "line direction component is outside the supported domain",
context);
224 line.
direction.push_back(std::move(simplified.value()));
229 }
catch (
const std::bad_alloc&) {
231 "vector geometry allocation failed",
233 }
catch (
const std::exception&
e) {
235 e.what(), operation);
240 const std::vector<std::shared_ptr<SymbolicExpr>>& p1,
241 const std::vector<std::shared_ptr<SymbolicExpr>>&
p2) {
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
ExpressionResult skew_distance_from_directions(const std::vector< std::shared_ptr< SymbolicExpr > > &direction1, const std::vector< std::shared_ptr< SymbolicExpr > > &direction2, const std::vector< std::shared_ptr< SymbolicExpr > > &difference, double point_scale, ComputationContext &context, const std::string &operation)
Result< double > point_difference_scale_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &p1, const std::vector< std::shared_ptr< SymbolicExpr > > &p2, ComputationContext &context, const std::string &operation, std::vector< double > &p1_values, std::vector< double > &p2_values)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
Result< double > numeric_vector_scale_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &expressions, ComputationContext &context, const std::string &operation, std::vector< double > *values=nullptr)
ExpressionResult simplify_checked(const std::shared_ptr< SymbolicExpr > &expr, const std::string &operation, const std::string &message, ComputationContext &context)
Result< void > validate_line_checked(const LineSymbolic &line, ComputationContext &context, const std::string &operation)
Result< void > validate_same_dimension_vectors(const std::vector< std::shared_ptr< SymbolicExpr > > &a, const std::vector< std::shared_ptr< SymbolicExpr > > &b, ComputationContext &context, const std::string &operation)
Result< void > checked_nonzero_numeric_vector(const std::vector< std::shared_ptr< SymbolicExpr > > &expressions, ComputationContext &context, const std::string &operation, const std::string &domain_message, const std::string &inconclusive_message)
VectorExprListResult vector_cross_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &a, const std::vector< std::shared_ptr< SymbolicExpr > > &b, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
LineSymbolicResult line_from_two_points_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &p1, const std::vector< std::shared_ptr< SymbolicExpr > > &p2, ComputationContext &context)
__attribute__((visibility("default"))) ExpressionResult point_plane_distance_checked(const std __attribute__((visibility("default"))) ExpressionResult point_plane_distance_checked(const std const LineSymbolic & l2
Result< std::shared_ptr< SymbolicExpr > > ExpressionResult
Result of an operation that produces a symbolic expression.
std::vector< std::shared_ptr< SymbolicExpr > > point
直线上一点。
__attribute__((visibility("default"))) LineSymbolicResult line_from_two_points_checked(const std __attribute__((visibility("default"))) LineSymbolicResult line_from_two_points_checked(const std __attribute__((visibility("default"))) PlaneSymbolicResult plane_from_three_points_checked(const std __attribute__((visibility("default"))) PlaneSymbolicResult plane_from_three_points_checked(const std const PlaneSymbolic & p2
Result< LineSymbolic > LineSymbolicResult
std::vector< std::shared_ptr< SymbolicExpr > > direction
方向向量。
ExpressionResult skew_lines_distance_checked(const LineSymbolic &l1, const LineSymbolic &l2, ComputationContext &context)
ExpressionResult vector_dot_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &a, const std::vector< std::shared_ptr< SymbolicExpr > > &b, ComputationContext &context)