Функции Camera.Parameters getHor horizontalViewAngle () и getVerticalViewAngle () предоставляют базовые углы обзора. Я говорю «базовый», потому что они применяются только к самой камере в состоянии без увеличения, а значения, возвращаемые этими функциями, не меняются даже при изменении угла обзора.
Camera.Parameters p = camera.getParameters();
double thetaV = Math.toRadians(p.getVerticalViewAngle());
double thetaH = Math.toRadians(p.getHorizontalViewAngle());
Две вещи приводят к изменению вашего «эффективного» угла обзора: масштабирование и использование формата предварительного просмотра, который не соответствует формату камеры.
Basic Math
Тригонометрия поля зрения (Θ) довольно проста:
загар (Θ / 2) = х / 2z
x = 2z загар (Θ / 2)
x - линейное расстояние, видимое на расстоянии z; то есть, если вы держите линейку на расстоянии z = 1 метр, вы сможете увидеть x метров этой линейки.
Например, на моей камере горизонтальное поле зрения составляет 52,68 °, а вертикальное поле зрения - 40,74 °. Преобразуйте их в радианы и вставьте их в формулу с произвольным значением z, равным 100 м, и вы получите значения x, равные 99,0 м (по горизонтали) и 74,2 м (по вертикали). Это соотношение сторон 4: 3.
Увеличить
Применение этой математики к уровням масштабирования лишь немного сложнее. Теперь x остается постоянным, и z изменяется в известном соотношении; мы должны определить Θ.
загар (Θ / 2) = х / (2z)
tan (Θ '/ 2) = x / (2z')
Θ '= 2 атан ((z / z') tan (Θ / 2))
Где z - базовый уровень масштабирования (100), z '- текущий уровень масштабирования (из CameraParameters.getZoomRatios), Θ - базовое горизонтальное / вертикальное поле обзора, а Θ' - эффективное поле обзора. Добавление степеней-> радианных преобразований делает это довольно многословным.
private static double zoomAngle(double degrees, int zoom) {
double theta = Math.toRadians(degrees);
return 2d * Math.atan(100d * Math.tan(theta / 2d) / zoom);
}
Camera.Parameters p = camera.getParameters();
int zoom = p.getZoomRatios().get(p.getZoom()).intValue();
double thetaH = zoomAngle(p.getHorizontalViewAngle(), zoom);
double thetaV = zoomAngle(p.getVerticalViewAngle(), zoom);
Соотношение сторон
Хотя типичная камера имеет соотношение сторон 4: 3, предварительный просмотр также может быть доступен в соотношениях 5: 3 и 16: 9, и, похоже, это достигается за счет фактического расширения горизонтального поля зрения. Это кажется недокументированным, а значит ненадежным, но если предположить, что это так, мы можем рассчитать поле зрения.
Математика похожа на вычисления масштаба; однако в этом случае z остается постоянным, и меняется x. Предполагая, что вертикальный угол обзора остается неизменным, в то время как горизонтальный угол обзора изменяется при изменении соотношения сторон, можно рассчитать новый эффективный горизонтальный угол обзора.
tan (Θ / 2) = v / (2z)
загар (Θ '/ 2) = ч / (2z)
2z = v / tan (Θ / 2)
Θ '= 2 атан ((ч / об) tan (Θ / 2))
Здесь h / v - соотношение сторон, а Θ - базовое вертикальное поле зрения, а Θ '- эффективное горизонтальное поле зрения.
Camera.Parameters p = camera.getParameters();
int zoom = p.getZoomRatios().get(p.getZoom()).intValue();
Camera.Size sz = p.getPreviewSize();
double aspect = (double) sz.width / (double) sz.height;
double thetaV = Math.toRadians(p.getVerticalViewAngle());
double thetaH = 2d * Math.atan(aspect * Math.tan(thetaV / 2));
thetaV = 2d * Math.atan(100d * Math.tan(thetaV / 2d) / zoom);
thetaH = 2d * Math.atan(100d * Math.tan(thetaH / 2d) / zoom);
Как я уже говорил выше, поскольку это, по-видимому, недокументировано, это просто предположение, что оно будет применяться ко всем устройствам; это следует считать хаком. Правильным решением было бы разделение нового набора функций getCurrentHor horizontalViewAngle и getCurrentVerticalViewAngle.