ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
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>
23#include <utils/math/abs.hpp>
25
26namespace Shapes {
28 double &dist,
29 Utils::Vector3d &vec) const {
30
31 /* Transform pos to the frame of the frustum (origin = center, z = axis, x =
32 * orientation, y = cross(z,x) ). Get the angle relative to orientation to
33 * determine whether pos is in the gap defined by m_central_angle or not.
34 */
35 auto const hcf_frame_y_axis = Utils::vector_product(
36 m_cyl_transform_params->axis(), m_cyl_transform_params->orientation());
37 auto const pos_hcf_frame = Utils::basis_change(
38 m_cyl_transform_params->orientation(), hcf_frame_y_axis,
39 m_cyl_transform_params->axis(), pos - m_cyl_transform_params->center());
40 auto const pos_phi =
42
43 /* The closest point of the frustum to pos will be determined by projection
44 * onto a line. Which line, depends on where pos is relative to the frustum
45 * gap. If pos is not within the gap region of central_angle, the closest
46 * point will be in the plane defined by axis and pos_cyl, as shown in the
47 * figure below:
48 *
49 * r1
50 * * ----->X r1_endpoint
51 * ^ a \
52 * | x \
53 * | i \
54 * | s \ *pos_hcf_frame
55 * X center \
56 * | \
57 * | X pos_closest (to be determined)
58 * | \
59 * | r2 \
60 * ----------------->X r2_endpoint
61 *
62 * In this case, the line is the intersection between the frustum and the
63 * plane of interest. The endpoints of the line are determined by the radii of
64 * the frustum, its length and the phi-coordinate of the plane.
65 *
66 * If pos is in the gap region, the projection must be made onto the closest
67 * edge (imagine pos is out-of-plane in the figure). In this case, for the
68 * endpoints we do not use the phi-coordinate of pos_cyl, but instead the
69 * phi-coordinate of the closer gap edge.
70 */
71
72 auto endpoint_angle = pos_phi;
73 if (Utils::abs(pos_phi) < m_central_angle / 2.) {
74 // Cannot use Utils::sgn because of pos_phi==0 corner case
75 endpoint_angle =
76 pos_phi > 0. ? m_central_angle / 2. : -m_central_angle / 2.;
77 }
78
80 Utils::Vector3d{{m_r1, endpoint_angle, m_length / 2.}});
82 Utils::Vector3d{{m_r2, endpoint_angle, -m_length / 2.}});
83 auto const line_director = (r2_endpoint - r1_endpoint).normalized();
84
85 auto project_on_line = [](auto const vec, auto const line_start,
86 auto const line_director) {
87 return line_start + line_director * ((vec - line_start) * line_director);
88 };
89
90 auto pos_closest_hcf_frame =
91 project_on_line(pos_hcf_frame, r1_endpoint, line_director);
92
93 /* It can be that the projection onto the (infinite) line is outside the
94 * frustum. In that case, the closest point is actually one of the endpoints.
95 */
96 if (Utils::abs(pos_closest_hcf_frame[2]) > m_length / 2.) {
97 pos_closest_hcf_frame =
98 pos_closest_hcf_frame[2] > 0. ? r1_endpoint : r2_endpoint;
99 }
100
101 // calculate distance and distance vector respecting thickness and direction
102 auto const u = (pos_hcf_frame - pos_closest_hcf_frame).normalize();
103 auto const d =
104 (pos_hcf_frame - pos_closest_hcf_frame).norm() - 0.5 * m_thickness;
105
106 // dist does not depend on reference frame, it can be calculated in the hcf
107 // frame.
108 dist = d * m_direction;
109
110 // vec must be rotated back to the original frame
111 auto const vec_hcf_frame = d * u;
112 vec = Utils::basis_change(m_cyl_transform_params->orientation(),
113 hcf_frame_y_axis, m_cyl_transform_params->axis(),
114 vec_hcf_frame, true);
115}
116} // namespace Shapes
Vector implementation and trait types for boost qvm interoperability.
__shared__ int pos[MAXDEPTH *THREADS5/WARPSIZE]
float u[3]
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:353
DEVICE_QUALIFIER double abs(double x)
Return the absolute value of x.
Definition abs.hpp:32
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.