jaulib v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
fov_hv_halves.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11
12#ifndef JAU_MATH_FOV_HV_HALVES_HPP_
13#define JAU_MATH_FOV_HV_HALVES_HPP_
14
15#include <cmath>
16#include <cstdarg>
17#include <string>
18
19#include <jau/float_math.hpp>
20
21namespace jau::math {
22
23 /** \addtogroup Math
24 *
25 * @{
26 */
27
28/**
29 * Horizontal and vertical field of view (FOV) halves,
30 * allowing a non-centered projection.
31 * <p>
32 * The values might be either in tangent or radians.
33 * </p>
34 */
36 public:
37 /** Half horizontal FOV from center to left, either in {@link #inTangents} or radians. */
38 float left;
39 /** Half horizontal FOV from center to right, either in {@link #inTangents} or radians. */
40 float right;
41 /** Half vertical FOV from center to top, either in {@link #inTangents} or radians. */
42 float top;
43 /** Half vertical FOV from center to bottom, either in {@link #inTangents} or radians. */
44 float bottom;
45 /** If true, values are in tangent, otherwise radians.*/
47
48 /**
49 * Constructor for one {@link FovHVHalves} instance.
50 * <p>
51 * It is recommended to pass and store values in tangent
52 * if used for perspective FOV calculations, since it will avoid conversion to tangent later on.
53 * </p>
54 * @param left_ half horizontal FOV, left side, in tangent or radians
55 * @param right_ half horizontal FOV, right side, in tangent or radians
56 * @param top_ half vertical FOV, top side, in tangent or radians
57 * @param bottom_ half vertical FOV, bottom side, in tangent or radians
58 * @param inTangents_ if true, values are in tangent, otherwise radians
59 */
60 constexpr FovHVHalves(const float left_, const float right_, const float top_, const float bottom_, const bool inTangents_) noexcept
61 : left(left_), right(right_), top(top_), bottom(bottom_), inTangents(inTangents_) {}
62
63 constexpr FovHVHalves(const FovHVHalves& o) noexcept = default;
64 constexpr FovHVHalves(FovHVHalves&& o) noexcept = default;
65 constexpr FovHVHalves& operator=(const FovHVHalves&) noexcept = default;
66 constexpr FovHVHalves& operator=(FovHVHalves&&) noexcept = default;
67
68 /**
69 * Returns a symmetrical centered {@link FovHVHalves} instance in {@link #inTangents}, using:
70 * <pre>
71 halfHorizFovTan = tan( horizontalFov / 2f );
72 halfVertFovTan = tan( verticalFov / 2f );
73 * </pre>
74 * @param horizontalFov whole horizontal FOV in radians
75 * @param verticalFov whole vertical FOV in radians
76 */
77 static FovHVHalves byRadians(const float horizontalFov, const float verticalFov) noexcept {
78 const float halfHorizFovTan = std::tan(horizontalFov/2.0f);
79 const float halfVertFovTan = std::tan(verticalFov/2.0f);
80 return FovHVHalves(halfHorizFovTan, halfHorizFovTan, halfVertFovTan, halfVertFovTan, true);
81 }
82
83 /**
84 * Returns a symmetrical centered {@link FovHVHalves} instance in {@link #inTangents}, using:
85 * <pre>
86 top = bottom = tan( verticalFov / 2f );
87 left = right = aspect * top;
88 * </pre>
89 *
90 * @param verticalFov vertical FOV in radians
91 * @param aspect aspect ration width / height
92 */
93 static FovHVHalves byFovyRadianAndAspect(const float verticalFov, const float aspect) noexcept {
94 const float halfVertFovTan = std::tan(verticalFov/2.0f);
95 const float halfHorizFovTan = aspect * halfVertFovTan;
96 return FovHVHalves(halfHorizFovTan, halfHorizFovTan,
97 halfVertFovTan, halfVertFovTan, true);
98 }
99
100 /**
101 * Returns a custom symmetry {@link FovHVHalves} instance {@link #inTangents}, using:
102 * <pre>
103 left = tan( horizontalFov * horizCenterFromLeft )
104 right = tan( horizontalFov * ( 1f - horizCenterFromLeft ) )
105 top = tan( verticalFov * vertCenterFromTop )
106 bottom = tan( verticalFov * (1f - vertCenterFromTop ) )
107 * </pre>
108 * @param horizontalFov whole horizontal FOV in radians
109 * @param horizCenterFromLeft horizontal center from left in [0..1]
110 * @param verticalFov whole vertical FOV in radians
111 * @param vertCenterFromTop vertical center from top in [0..1]
112 */
113 static FovHVHalves byRadians(const float horizontalFov, const float horizCenterFromLeft,
114 const float verticalFov, const float vertCenterFromTop) noexcept {
115 return FovHVHalves(std::tan(horizontalFov * horizCenterFromLeft),
116 std::tan(horizontalFov * ( 1.0f - horizCenterFromLeft )),
117 std::tan(verticalFov * vertCenterFromTop),
118 std::tan(verticalFov * (1.0f - vertCenterFromTop )),
119 true);
120 }
121
122 /**
123 * Returns a custom symmetry {@link FovHVHalves} instance {@link #inTangents},
124 * via computing the <code>horizontalFov</code> using:
125 * <pre>
126 halfVertFovTan = tan( verticalFov / 2f );
127 halfHorizFovTan = aspect * halfVertFovTan;
128 horizontalFov = atan( halfHorizFovTan ) * 2f;
129 return {@link #byRadians(float, float, float, float) byRadians}(horizontalFov, horizCenterFromLeft, verticalFov, vertCenterFromTop)
130 * </pre>
131 * @param verticalFov whole vertical FOV in radians
132 * @param vertCenterFromTop vertical center from top in [0..1]
133 * @param aspect aspect ration width / height
134 * @param horizCenterFromLeft horizontal center from left in [0..1]
135 */
136 static FovHVHalves byFovyRadianAndAspect(const float verticalFov, const float vertCenterFromTop,
137 const float aspect, const float horizCenterFromLeft) noexcept {
138 const float halfVertFovTan = std::tan(verticalFov/2.0f);
139 const float halfHorizFovTan = aspect * halfVertFovTan;
140 const float horizontalFov = std::atan(halfHorizFovTan) * 2.0f;
141 return byRadians(horizontalFov, horizCenterFromLeft, verticalFov, vertCenterFromTop);
142 }
143
144 /**
145 * Returns this instance <i>in tangent</i> values.
146 * <p>
147 * If this instance is {@link #inTangents} already, method returns a copy of this instance,
148 * otherwise a newly created instance w/ converted values to tangent.
149 * </p>
150 */
151 FovHVHalves toTangents() const noexcept {
152 if( inTangents ) {
153 return *this;
154 } else {
155 return FovHVHalves(std::tan(left), std::tan(right), std::tan(top), std::tan(bottom), true);
156 }
157 }
158
159 /** Returns the full horizontal FOV, i.e. {@link #left} + {@link #right}, either in {@link #inTangents} or radians. */
160 float horzFov() const noexcept { return left+right; }
161
162 /** Returns the full vertical FOV, i.e. {@link #top} + {@link #bottom}, either in {@link #inTangents} or radians. */
163 float vertFov() const noexcept { return top+bottom; }
164
165 std::string toString() const noexcept {
166 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]";
167 }
168
169 std::string toStringInDegrees() const noexcept {
170 const float f = 180.0f / M_PI;
171 std::string storedAs = inTangents?"tangents":"radians";
172 if( inTangents ) {
173 const float aleft = std::atan(left);
174 const float aright = std::atan(right);
175 const float atop = std::atan(top);
176 const float abottom = std::atan(bottom);
177 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+"]";
178 } else {
179 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+"]";
180 }
181 }
182};
183
184/**@}*/
185
186} // namespace jau::math
187
188#endif // JAU_MATH_FOV_HV_HALVES_HPP_
189
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.