16 using tvec = glm::tvec2<T>;
22 constexpr tsegment()
noexcept =
default;
23 constexpr tsegment(tvec
const& start, tvec
const& end) noexcept : start(start), end(end) {}
24 constexpr tsegment(std::pair<tvec, tvec>
const& p) noexcept : start(p.first), end(p.second) {}
26 constexpr tvec vec()
const noexcept {
return end - start; }
27 tvec dir()
const noexcept {
return glm::normalize(vec()); }
28 auto length()
const noexcept {
return glm::distance(start, end); }
29 constexpr auto center()
const noexcept {
return (start + end) / T(2); }
31 static constexpr tsegment from_offset(tvec
const& start, tvec
const& offset)
noexcept {
return { start, start + offset }; }
32 static constexpr tsegment from_dir(tvec
const& start, tvec
const& dir, T len)
noexcept {
return { start, start + dir * len }; }
33 static constexpr tsegment from_pair(std::pair<tvec, tvec>
const& p)
noexcept {
return { p.first, p.second }; }
37 tsegment& set_position(tvec
const& pos)
noexcept {
const auto d = vec(); start = pos; end = pos + d;
return *
this; }
38 tsegment& operator+=(tvec
const& offs)
noexcept { start += offs; end += offs;
return *
this; }
39 tsegment& operator-=(tvec
const& offs)
noexcept { start -= offs; end -= offs;
return *
this; }
40 tsegment& translate(tvec
const& offs)
noexcept {
return this->operator+=(offs); }
42 tsegment& set_length(T len)
noexcept { end = start + dir() * len;
return *
this; }
43 tsegment& set_length_around_center(T len)
noexcept
45 const auto c = center();
47 const auto hlen = len / T(2);
53 tsegment& grow(T len)
noexcept {
const auto d = dir(); start -= d * len; end += d * len;
return *
this; }
54 tsegment& shrink(T len)
noexcept {
const auto d = dir(); start += d * len; end -= d * len;
return *
this; }
56 constexpr std::optional<tvec> intersection(tsegment
const& other)
const noexcept
60 const auto s = other.vec();
61 const auto rxs = glm::cross(r, s);
62 const auto qp = other.start - start;
63 const auto qpxr = glm::cross(qp, r);
64 if (glm::abs(rxs) < std::numeric_limits<T>::epsilon() && glm::abs(qpxr) < std::numeric_limits<T>::epsilon())
67 const auto t0 = glm::dot(qp, r) / glm::dot(r, r);
68 const auto t1 = t0 + glm::dot(s, r) / glm::dot(r, r);
69 if ((t0 >= 0 && t0 <= 1) || (t1 >= 0 && t1 <= 1))
73 if (glm::abs(rxs) < std::numeric_limits<T>::epsilon() && glm::abs(qpxr) > std::numeric_limits<T>::epsilon())
75 const auto t = glm::cross(qp, s) / rxs;
76 const auto u = glm::cross(qp, r) / rxs;
77 if (rxs != 0 && t >= 0 && t <= 1 && u >= 0 && u <= 1)
85 tvec edge_point_alpha(T t)
const {
return glm::mix(start, end, t); }
86 tvec edge_point(T t)
const {
return glm::mix(start, end, t /
edge_length()); }
87 trec2<T> bounding_box()
const {
return trec2<T>::from_points({ &start, &start + 2 }); }
88 tvec closest_point_to(tvec pt)
const
90 const auto dir = this->vec();
91 const auto d1 = glm::dot(pt - start, dir);
94 const auto d2 = glm::dot(dir, dir);
97 return start + dir * (d1 / d2);
100 interval<T> projected_on_axis(tvec
const& axis)
const
102 const auto p0 = glm::dot(axis, start);
103 const auto p1 = glm::dot(axis, end);
104 return { std::min(p0, p1), std::max(p0, p1) };
109 template <
typename FUNC>
115 template <
typename FUNC>
116 void for_each_vertex(FUNC&& func)
const
122 size_t vertex_count()
const {
return 2; }
124 size_t edge_count()
const {
return 1; }
126 auto edge(
size_t index)
const -> std::optional<std::pair<glm::tvec2<T>, glm::tvec2<T>>>
129 return std::make_pair(start, end);
133 auto vertex(
size_t index)
const -> std::optional<tvec>