#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
double ComputePanelWidth2(double fovDegrees, double d, double r) {
double fovRadians = fovDegrees * M_PI / 180.0;
if (r == 0)
{
// Ensure width is non-negative
return 2.0f * d * std::tan(fovRadians / 2.0f);
}
float fovDistance = std::cos(fovRadians / 2.0f) * (d - r) + std::sqrt(r * r - std::pow((d - r) * std::sin(fovRadians / 2.0f), 2));
return 2.0f * fovDistance * std::sin(fovRadians / 2.0f);
}
double ComputePanelWidth(double fovDegrees, double d, double r) {
//double fovRadians = fovDegrees * M_PI / 180.0;
//return std::sin(fovRadians) * (d - r) + std::sqrt(r * r - std::pow((d - r) * std::cos(fovRadians), 2));
float targetWidth;
float fovRad = fovDegrees * M_PI / 180.0;
float fovHalfRad = fovRad / 2.0f;
if (r == 0)
{
targetWidth = 2.0f * d * std::tan(fovRad / 2.0f);
// Ensure width is non-negative
return std::max(0.0f, targetWidth);
}
// Precompute sin and cos of half FOV
float sinFovHalf = std::sin(fovHalfRad);
float cosFovHalf = std::cos(fovHalfRad);
// Calculate y_c = d - r (as per formula derivation)
float yc = d - r;
// Calculate term inside the square root: r² - y_c² * sin²(FOV/2)
float termInsideSqrt = (r * r) - (yc * yc * sinFovHalf * sinFovHalf);
// Check condition: term inside sqrt must be non-negative
if (termInsideSqrt >= 0)
{
// Calculate generalized t = cos(FOV/2)*y_c + sqrt( r² - y_c² * sin²(FOV/2) )
float t_generalized = cosFovHalf * yc + std::sqrt(termInsideSqrt);
// Check condition: t (distance to intersection) must be positive
if (t_generalized > 0)
{
// Calculate Panel Width = 2 * t * sin(FOV/2)
targetWidth = 2.0f * t_generalized * sinFovHalf;
}
else
{
// Intersection occurs behind the viewer or at the origin, width is effectively zero
targetWidth = 0.0f;
}
}
return targetWidth;
}
int main() {
// your code goes here
double fov = 60.0; // degrees
double d = 1.8;
double r = 0;
for (double nfov = 50; nfov <=68; nfov++)
{
std::cout << "Panel width fov: " << nfov << " " << ComputePanelWidth(nfov, d, r) << " " << ComputePanelWidth2(nfov, d, r) << std::endl;
}
return 0;
}