1+ /*
2+ * Copyright (c) 2019 - 2025 Geode-solutions
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+ * SOFTWARE.
21+ *
22+ */
23+
24+ #pragma once
25+
26+ #include < geode/geometry/basic_objects/segment.hpp>
27+ #include < geode/geometry/basic_objects/sphere.hpp>
28+
29+ #include < geode/stochastic/sampling/direct/object_set_sampler/object_set_sampler.hpp>
30+ #include < geode/stochastic/sampling/direct/point_uniform_sampler.hpp>
31+ #include < geode/stochastic/sampling/direct/segment_uniform_sampler.hpp>
32+
33+ namespace geode
34+ {
35+ class UniformSegmentSetSampler : public ObjectSetSampler < OwnerSegment2D >
36+ {
37+ public:
38+ UniformSegmentSetSampler ( const BoundingBox< 2 >& box,
39+ const DoubleSampler::Distribution& length,
40+ const DoubleSampler::Distribution& azimuth )
41+ : ObjectSetSampler< OwnerSegment2D >{},
42+ box_{ box },
43+ length_{ length },
44+ azimuth_{ azimuth }
45+ {
46+ auto volume = box_.n_volume ();
47+ OPENGEODE_EXCEPTION ( volume != 0 .,
48+ " [SegmentSetSampler] - Undefined Bounding Box (volume == 0)." );
49+ this ->log_pdf_ = -std::log ( volume );
50+ }
51+
52+ OwnerSegment2D sample ( RandomEngine& engine ) const override
53+ {
54+ auto seg = SegmentUniformSampler::sample (
55+ engine, box_, length_, azimuth_ );
56+ return seg;
57+ }
58+
59+ OwnerSegment2D change (
60+ const OwnerSegment2D& obj, RandomEngine& engine ) const override
61+ {
62+ double ratio = 0.1 ;
63+ const auto & extremities = obj.vertices ();
64+ const auto current =
65+ static_cast < local_index_t >( engine.sample_bernoulli ( 0.5 ) );
66+
67+ geode::Sphere< 2 > ball{ extremities[current],
68+ ratio * obj.length () };
69+
70+ auto new_point = PointUniformSampler::sample< 2 >( engine, ball );
71+ constexpr index_t max_try{ 100 };
72+ for ( const auto try_id : geode::Range{ max_try } )
73+ {
74+ if ( box_.contains ( new_point ) )
75+ {
76+ OwnerSegment2D new_segment{ obj };
77+ new_segment.set_point ( current, new_point );
78+ return new_segment;
79+ }
80+ new_point = PointUniformSampler::sample< 2 >( engine, ball );
81+ }
82+ throw OpenGeodeException ( absl::StrCat (
83+ " [PointSampler] - Cannot find a point in the box: " ,
84+ box_.string () ) );
85+ return obj;
86+ }
87+
88+ private:
89+ bool is_valid_object ( const OwnerSegment2D& obj ) const override
90+ {
91+ const auto & extremities = obj.vertices ();
92+
93+ return box_.contains ( extremities[0 ] )
94+ && box_.contains ( extremities[1 ] );
95+ }
96+
97+ private:
98+ BoundingBox2D box_;
99+ DoubleSampler::Distribution length_;
100+ DoubleSampler::Distribution azimuth_;
101+ };
102+
103+ } // namespace geode
0 commit comments