PLaSK library
Loading...
Searching...
No Matches
transform_space_cylindric.cpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2022 Lodz University of Technology
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
15#include "../manager.hpp"
16#include "reader.hpp"
17
18#define PLASK_REVOLUTION_NAME "revolution"
19
20namespace plask {
21
23
24std::string Revolution::getTypeName() const { return NAME; }
25
27 return this->hasChild() && this->_child->contains(childVec(p));
28}
29
30/*bool Revolution::intersects(const Box& area) const {
31 return getChild()->intersects(childBox(area));
32}*/
33
35 return this->hasChild() ? this->_child->getMaterial(childVec(p)) : shared_ptr<Material>();
36}
37
41
43
45 if (!this->hasChild()) return GeometryObject::Subtree();
46 return GeometryObject::Subtree::extendIfNotEmpty(this, this->_child->getPathsAt(childVec(point), all));
47}
48
50 std::vector<GeometryObjectTransformSpace::DVec>& dest,
51 const PathHints* path) const {
52 if (predicate(*this)) {
54 return;
55 }
56 if (!this->hasChild()) return;
57 auto child_pos_vec = this->_child->getPositions(predicate, path);
58 for (const auto& v : child_pos_vec)
59 dest.emplace_back(0., 0., v.vert() // only vert component is well defined
60 );
61}
62
64 return this->hasChild() && (this->_child->getBoundingBox().lower.tran() < 0);
65}
66
67// void Revolution::extractToVec(const GeometryObject::Predicate &predicate, std::vector< shared_ptr<const
68// GeometryObjectD<3> > >&dest, const PathHints *path) const {
69// if (predicate(*this)) {
70// dest.push_back(static_pointer_cast< const GeometryObjectD<3> >(this->shared_from_this()));
71// return;
72// }
73// std::vector< shared_ptr<const GeometryObjectD<2> > > child_res = getChild()->extract(predicate, path);
74// for (shared_ptr<const GeometryObjectD<2>>& c: child_res)
75// dest.emplace_back(new Revolution(const_pointer_cast<GeometryObjectD<2>>(c)));
76// }
77
78/*Box2D Revolution::childBox(const plask::Box3D& r) {
79 Box2D result(childVec(r.lower), childVec(r.upper));
80 result.fix();
81 return result;
82}*/ //TODO bugy
83
84Box3D Revolution::parentBox(const ChildBox& r) {
85 double tran = std::max(r.upper.tran(), 0.0);
86 return Box3D(vec(-tran, -tran, r.lower.vert()), vec(tran, tran, r.upper.vert()));
87}
88
89void Revolution::addPointsAlongToSet(std::set<double>& points,
90 Primitive<3>::Direction direction,
91 unsigned max_steps,
92 double min_step_size) const {
93 if (!this->hasChild()) return;
94 if (this->max_steps) max_steps = this->max_steps;
95 if (this->min_step_size) min_step_size = this->min_step_size;
96 if (direction == Primitive<3>::DIRECTION_VERT) {
97 this->_child->addPointsAlongToSet(points, Primitive<3>::DIRECTION_VERT, max_steps, min_step_size);
98 } else {
99 std::set<double> child_points;
100 this->_child->addPointsAlongToSet(child_points, Primitive<3>::DIRECTION_TRAN, max_steps, min_step_size);
101 if (child_points.size() == 0) return;
102 // Finer separation
103 std::vector<double> pts;
104 pts.reserve(child_points.size());
105 pts.insert(pts.end(), child_points.begin(), child_points.end());
106 double rr = pts[pts.size() - 1] - pts[0];
107 for (size_t i = 1; i < pts.size(); ++i) {
108 double r = pts[i - 1];
109 double dr = pts[i] - r;
110 unsigned maxsteps = rev_max_steps * (dr / rr);
111 unsigned steps = min(unsigned(dr / rev_min_step_size), maxsteps);
112 double step = dr / steps;
113 for (unsigned j = 0; j < steps; ++j) {
114 points.insert(-r - j * step);
115 points.insert(r + j * step);
116 }
117 }
118 points.insert(-pts[pts.size() - 1]);
119 points.insert(pts[pts.size() - 1]);
120 }
121}
122
123void Revolution::addLineSegmentsToSet(std::set<typename GeometryObjectD<3>::LineSegment>& segments,
124 unsigned max_steps,
125 double min_step_size) const {
126 if (!this->hasChild()) return;
127 typedef typename GeometryObjectD<3>::LineSegment Segment;
128 if (this->max_steps) max_steps = this->max_steps;
129 if (this->min_step_size) min_step_size = this->min_step_size;
130 std::set<typename GeometryObjectD<2>::LineSegment> segments2;
131 this->_child->addLineSegmentsToSet(segments2, max_steps, min_step_size);
132 double radius = max(abs(this->_child->getBoundingBox().left()), abs(this->_child->getBoundingBox().right()));
133 unsigned steps = min(unsigned(M_PI * radius / min_step_size), max_steps);
134 double dphi = M_PI / steps;
135 double cos0 = 1., sin0 = 0;
136 for (unsigned i = 1; i <= (steps + 1) / 2; ++i) {
137 double phi = dphi * i;
138 double cos1 = cos(phi), sin1 = sin(phi);
139 for (auto seg : segments2) {
140 double x[2], y[2], z[2];
141 for (int j = 0; j < 2; ++i) {
142 x[j] = seg[j].c0 * cos1;
143 y[j] = seg[j].c0 * sin1;
144 z[j] = seg[j].c1;
145 double x0 = seg[j].c0 * cos0, y0 = seg[j].c0 * cos0;
146 segments.insert(Segment(DVec(-x0, -y0, z[j]), DVec(-x[j], -y[j], z[j])));
147 segments.insert(Segment(DVec(x0, -y0, z[j]), DVec(x[j], -y[j], z[j])));
148 segments.insert(Segment(DVec(-x0, y0, z[j]), DVec(-x[j], y[j], z[j])));
149 segments.insert(Segment(DVec(x0, y0, z[j]), DVec(x[j], y[j], z[j])));
150 }
151 segments.insert(Segment(DVec(-x[0], -y[0], z[0]), DVec(-x[1], -y[1], z[1])));
152 segments.insert(Segment(DVec(x[0], -y[0], z[0]), DVec(x[1], -y[1], z[1])));
153 segments.insert(Segment(DVec(-x[0], y[0], z[0]), DVec(-x[1], y[1], z[1])));
154 segments.insert(Segment(DVec(x[0], y[0], z[0]), DVec(x[1], y[1], z[1])));
155 }
156 cos0 = cos1;
157 sin0 = sin1;
158 }
159}
160
163 bool auto_clip = reader.source.getAttribute("auto-clip", false);
164 auto rev_max_steps = reader.source.getAttribute<unsigned>("rev-steps-num");
165 auto rev_min_step_size = reader.source.getAttribute<double>("rev-steps-dist");
166 auto revolution = plask::make_shared<Revolution>(
168 if (rev_max_steps) revolution->rev_max_steps = *rev_max_steps;
169 if (rev_min_step_size) revolution->rev_min_step_size = *rev_min_step_size;
170 return revolution;
171 /*if (res->childIsClipped()) {
172 writelog(LOG_WARNING, "Child of <revolution>, read from XPL line {0}, is implicitly clipped (to non-negative
173 tran. coordinates).", line_nr);
174 }*/
175}
176
177static GeometryReader::RegisterObjectReader revolution_reader(PLASK_REVOLUTION_NAME, read_revolution);
178
179} // namespace plask