Loading [MathJax]/jax/output/HTML-CSS/config.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
HollowConicalFrustum.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <shapes/HollowConicalFrustum.hpp>
21
22#include <utils/Vector.hpp>
24
25#include <cmath>
26
27namespace Shapes {
29 double &dist,
30 Utils::Vector3d &vec) const {
31
32 /* Transform pos to the frame of the frustum (origin = center, z = axis, x =
33 * orientation, y = cross(z,x) ). Get the angle relative to orientation to
34 * determine whether pos is in the gap defined by m_central_angle or not.
35 */
36 auto const hcf_frame_y_axis = Utils::vector_product(
37 m_cyl_transform_params->axis(), m_cyl_transform_params->orientation());
38 auto const pos_hcf_frame = Utils::basis_change(
39 m_cyl_transform_params->orientation(), hcf_frame_y_axis,
40 m_cyl_transform_params->axis(), pos - m_cyl_transform_params->center());
41 auto const pos_phi =
43
44 /* The closest point of the frustum to pos will be determined by projection
45 * onto a line. Which line, depends on where pos is relative to the frustum
46 * gap. If pos is not within the gap region of central_angle, the closest
47 * point will be in the plane defined by axis and pos_cyl, as shown in the
48 * figure below:
49 *
50 * r1
51 * * ----->X r1_endpoint
52 * ^ a \
53 * | x \
54 * | i \
55 * | s \ *pos_hcf_frame
56 * X center \
57 * | \
58 * | X pos_closest (to be determined)
59 * | \
60 * | r2 \
61 * ----------------->X r2_endpoint
62 *
63 * In this case, the line is the intersection between the frustum and the
64 * plane of interest. The endpoints of the line are determined by the radii of
65 * the frustum, its length and the phi-coordinate of the plane.
66 *
67 * If pos is in the gap region, the projection must be made onto the closest
68 * edge (imagine pos is out-of-plane in the figure). In this case, for the
69 * endpoints we do not use the phi-coordinate of pos_cyl, but instead the
70 * phi-coordinate of the closer gap edge.
71 */
72
73 auto endpoint_angle = pos_phi;
74 if (std::fabs(pos_phi) < m_central_angle / 2.) {
75 // Cannot use Utils::sgn because of pos_phi==0 corner case
76 endpoint_angle =
77 pos_phi > 0. ? m_central_angle / 2. : -m_central_angle / 2.;
78 }
79
81 Utils::Vector3d{{m_r1, endpoint_angle, m_length / 2.}});
83 Utils::Vector3d{{m_r2, endpoint_angle, -m_length / 2.}});
84 auto const line_director = (r2_endpoint - r1_endpoint).normalized();
85
86 auto project_on_line = [](auto const vec, auto const line_start,
87 auto const line_director) {
88 return line_start + line_director * ((vec - line_start) * line_director);
89 };
90
91 auto pos_closest_hcf_frame =
92 project_on_line(pos_hcf_frame, r1_endpoint, line_director);
93
94 /* It can be that the projection onto the (infinite) line is outside the
95 * frustum. In that case, the closest point is actually one of the endpoints.
96 */
97 if (std::fabs(pos_closest_hcf_frame[2]) > m_length / 2.) {
98 pos_closest_hcf_frame =
99 pos_closest_hcf_frame[2] > 0. ? r1_endpoint : r2_endpoint;
100 }
101
102 // calculate distance and distance vector respecting thickness and direction
103 auto const u = (pos_hcf_frame - pos_closest_hcf_frame).normalize();
104 auto const d =
105 (pos_hcf_frame - pos_closest_hcf_frame).norm() - 0.5 * m_thickness;
106
107 // dist does not depend on reference frame, it can be calculated in the hcf
108 // frame.
109 dist = d * m_direction;
110
111 // vec must be rotated back to the original frame
112 auto const vec_hcf_frame = d * u;
113 vec = Utils::basis_change(m_cyl_transform_params->orientation(),
114 hcf_frame_y_axis, m_cyl_transform_params->axis(),
115 vec_hcf_frame, true);
116}
117} // namespace Shapes
Vector implementation and trait types for boost qvm interoperability.
void calculate_dist(const Utils::Vector3d &pos, double &dist, Utils::Vector3d &vec) const override
Calculate the distance vector and its norm between a given position and the cone.
Convert coordinates from the Cartesian system to the cylindrical system.
Vector< T, 3 > vector_product(Vector< T, 3 > const &a, Vector< T, 3 > const &b)
Definition Vector.hpp:369
Vector3d transform_coordinate_cylinder_to_cartesian(Vector3d const &pos)
Coordinate transformation from cylindrical to Cartesian coordinates.
Vector3d transform_coordinate_cartesian_to_cylinder(Vector3d const &pos)
Coordinate transformation from Cartesian to cylindrical coordinates.
Vector3d basis_change(Vector3d const &b1, Vector3d const &b2, Vector3d const &b3, Vector3d const &v, bool reverse=false)
Basis change.