jaulib v1.3.0
Jau Support Library (C++, Java, ..)
fov_hv_halves.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2010-2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#ifndef JAU_FOV_HV_HALVES_HPP_
25#define JAU_FOV_HV_HALVES_HPP_
26
27#include <cmath>
28#include <cstdarg>
29#include <cstdint>
30#include <limits>
31#include <string>
32
33#include <jau/float_math.hpp>
34
35namespace jau::math {
36
37 /** \addtogroup Math
38 *
39 * @{
40 */
41
42/**
43 * Horizontal and vertical field of view (FOV) halves,
44 * allowing a non-centered projection.
45 * <p>
46 * The values might be either in tangent or radians.
47 * </p>
48 */
50 public:
51 /** Half horizontal FOV from center to left, either in {@link #inTangents} or radians. */
52 float left;
53 /** Half horizontal FOV from center to right, either in {@link #inTangents} or radians. */
54 float right;
55 /** Half vertical FOV from center to top, either in {@link #inTangents} or radians. */
56 float top;
57 /** Half vertical FOV from center to bottom, either in {@link #inTangents} or radians. */
58 float bottom;
59 /** If true, values are in tangent, otherwise radians.*/
61
62 /**
63 * Constructor for one {@link FovHVHalves} instance.
64 * <p>
65 * It is recommended to pass and store values in tangent
66 * if used for perspective FOV calculations, since it will avoid conversion to tangent later on.
67 * </p>
68 * @param left_ half horizontal FOV, left side, in tangent or radians
69 * @param right_ half horizontal FOV, right side, in tangent or radians
70 * @param top_ half vertical FOV, top side, in tangent or radians
71 * @param bottom_ half vertical FOV, bottom side, in tangent or radians
72 * @param inTangents_ if true, values are in tangent, otherwise radians
73 */
74 constexpr FovHVHalves(const float left_, const float right_, const float top_, const float bottom_, const bool inTangents_) noexcept
75 : left(left_), right(right_), top(top_), bottom(bottom_), inTangents(inTangents_) {}
76
77 constexpr FovHVHalves(const FovHVHalves& o) noexcept = default;
78 constexpr FovHVHalves(FovHVHalves&& o) noexcept = default;
79 constexpr FovHVHalves& operator=(const FovHVHalves&) noexcept = default;
80 constexpr FovHVHalves& operator=(FovHVHalves&&) noexcept = default;
81
82 /**
83 * Returns a symmetrical centered {@link FovHVHalves} instance in {@link #inTangents}, using:
84 * <pre>
85 halfHorizFovTan = tan( horizontalFov / 2f );
86 halfVertFovTan = tan( verticalFov / 2f );
87 * </pre>
88 * @param horizontalFov whole horizontal FOV in radians
89 * @param verticalFov whole vertical FOV in radians
90 */
91 static FovHVHalves byRadians(const float horizontalFov, const float verticalFov) noexcept {
92 const float halfHorizFovTan = std::tan(horizontalFov/2.0f);
93 const float halfVertFovTan = std::tan(verticalFov/2.0f);
94 return FovHVHalves(halfHorizFovTan, halfHorizFovTan, halfVertFovTan, halfVertFovTan, true);
95 }
96
97 /**
98 * Returns a symmetrical centered {@link FovHVHalves} instance in {@link #inTangents}, using:
99 * <pre>
100 top = bottom = tan( verticalFov / 2f );
101 left = right = aspect * top;
102 * </pre>
103 *
104 * @param verticalFov vertical FOV in radians
105 * @param aspect aspect ration width / height
106 */
107 static FovHVHalves byFovyRadianAndAspect(const float verticalFov, const float aspect) noexcept {
108 const float halfVertFovTan = std::tan(verticalFov/2.0f);
109 const float halfHorizFovTan = aspect * halfVertFovTan;
110 return FovHVHalves(halfHorizFovTan, halfHorizFovTan,
111 halfVertFovTan, halfVertFovTan, true);
112 }
113
114 /**
115 * Returns a custom symmetry {@link FovHVHalves} instance {@link #inTangents}, using:
116 * <pre>
117 left = tan( horizontalFov * horizCenterFromLeft )
118 right = tan( horizontalFov * ( 1f - horizCenterFromLeft ) )
119 top = tan( verticalFov * vertCenterFromTop )
120 bottom = tan( verticalFov * (1f - vertCenterFromTop ) )
121 * </pre>
122 * @param horizontalFov whole horizontal FOV in radians
123 * @param horizCenterFromLeft horizontal center from left in [0..1]
124 * @param verticalFov whole vertical FOV in radians
125 * @param vertCenterFromTop vertical center from top in [0..1]
126 */
127 static FovHVHalves byRadians(const float horizontalFov, const float horizCenterFromLeft,
128 const float verticalFov, const float vertCenterFromTop) noexcept {
129 return FovHVHalves(std::tan(horizontalFov * horizCenterFromLeft),
130 std::tan(horizontalFov * ( 1.0f - horizCenterFromLeft )),
131 std::tan(verticalFov * vertCenterFromTop),
132 std::tan(verticalFov * (1.0f - vertCenterFromTop )),
133 true);
134 }
135
136 /**
137 * Returns a custom symmetry {@link FovHVHalves} instance {@link #inTangents},
138 * via computing the <code>horizontalFov</code> using:
139 * <pre>
140 halfVertFovTan = tan( verticalFov / 2f );
141 halfHorizFovTan = aspect * halfVertFovTan;
142 horizontalFov = atan( halfHorizFovTan ) * 2f;
143 return {@link #byRadians(float, float, float, float) byRadians}(horizontalFov, horizCenterFromLeft, verticalFov, vertCenterFromTop)
144 * </pre>
145 * @param verticalFov whole vertical FOV in radians
146 * @param vertCenterFromTop vertical center from top in [0..1]
147 * @param aspect aspect ration width / height
148 * @param horizCenterFromLeft horizontal center from left in [0..1]
149 */
150 static FovHVHalves byFovyRadianAndAspect(const float verticalFov, const float vertCenterFromTop,
151 const float aspect, const float horizCenterFromLeft) noexcept {
152 const float halfVertFovTan = std::tan(verticalFov/2.0f);
153 const float halfHorizFovTan = aspect * halfVertFovTan;
154 const float horizontalFov = std::atan(halfHorizFovTan) * 2.0f;
155 return byRadians(horizontalFov, horizCenterFromLeft, verticalFov, vertCenterFromTop);
156 }
157
158 /**
159 * Returns this instance <i>in tangent</i> values.
160 * <p>
161 * If this instance is {@link #inTangents} already, method returns a copy of this instance,
162 * otherwise a newly created instance w/ converted values to tangent.
163 * </p>
164 */
165 FovHVHalves toTangents() const noexcept {
166 if( inTangents ) {
167 return *this;
168 } else {
169 return FovHVHalves(std::tan(left), std::tan(right), std::tan(top), std::tan(bottom), true);
170 }
171 }
172
173 /** Returns the full horizontal FOV, i.e. {@link #left} + {@link #right}, either in {@link #inTangents} or radians. */
174 float horzFov() const noexcept { return left+right; }
175
176 /** Returns the full vertical FOV, i.e. {@link #top} + {@link #bottom}, either in {@link #inTangents} or radians. */
177 float vertFov() const noexcept { return top+bottom; }
178
179 std::string toString() const noexcept {
180 return "FovHVH["+(inTangents?std::string("tangents"):std::string("radians"))+": "+std::to_string(left)+" l, "+std::to_string(right)+" r, "+std::to_string(top)+" t, "+std::to_string(bottom)+" b]";
181 }
182
183 std::string toStringInDegrees() const noexcept {
184 const float f = 180.0f / M_PI;
185 std::string storedAs = inTangents?"tangents":"radians";
186 if( inTangents ) {
187 const float aleft = std::atan(left);
188 const float aright = std::atan(right);
189 const float atop = std::atan(top);
190 const float abottom = std::atan(bottom);
191 return "FovHVH[degrees: "+std::to_string(aleft*f)+" l, "+std::to_string(aright*f)+" r, "+std::to_string(atop*f)+" t, "+std::to_string(abottom*f)+" b, stored-as: "+storedAs+"]";
192 } else {
193 return "FovHVH[degrees: "+std::to_string(left*f)+" l, "+std::to_string(right*f)+" r, "+std::to_string(top*f)+" t, "+std::to_string(bottom*f)+" b, stored-as: "+storedAs+"]";
194 }
195 }
196};
197
198/**@}*/
199
200} // namespace jau::math
201
202#endif // JAU_FOV_HV_HALVES_HPP_
203
Horizontal and vertical field of view (FOV) halves, allowing a non-centered projection.
bool inTangents
If true, values are in tangent, otherwise radians.
static FovHVHalves byFovyRadianAndAspect(const float verticalFov, const float aspect) noexcept
Returns a symmetrical centered FovHVHalves instance in inTangents, using:
static FovHVHalves byRadians(const float horizontalFov, const float verticalFov) noexcept
Returns a symmetrical centered FovHVHalves instance in inTangents, using:
float top
Half vertical FOV from center to top, either in inTangents or radians.
static FovHVHalves byRadians(const float horizontalFov, const float horizCenterFromLeft, const float verticalFov, const float vertCenterFromTop) noexcept
Returns a custom symmetry FovHVHalves instance inTangents, using:
float right
Half horizontal FOV from center to right, either in inTangents or radians.
constexpr FovHVHalves & operator=(FovHVHalves &&) noexcept=default
std::string toStringInDegrees() const noexcept
constexpr FovHVHalves(const float left_, const float right_, const float top_, const float bottom_, const bool inTangents_) noexcept
Constructor for one FovHVHalves instance.
static FovHVHalves byFovyRadianAndAspect(const float verticalFov, const float vertCenterFromTop, const float aspect, const float horizCenterFromLeft) noexcept
Returns a custom symmetry FovHVHalves instance inTangents, via computing the horizontalFov using:
constexpr FovHVHalves(FovHVHalves &&o) noexcept=default
float left
Half horizontal FOV from center to left, either in inTangents or radians.
constexpr FovHVHalves(const FovHVHalves &o) noexcept=default
std::string toString() const noexcept
FovHVHalves toTangents() const noexcept
Returns this instance in tangent values.
float vertFov() const noexcept
Returns the full vertical FOV, i.e.
constexpr FovHVHalves & operator=(const FovHVHalves &) noexcept=default
float horzFov() const noexcept
Returns the full horizontal FOV, i.e.
float bottom
Half vertical FOV from center to bottom, either in inTangents or radians.
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97