You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel.ML/LocationMath/ViewMath.cs

80 lines
3.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using ZeroLevel.ML.Models;
namespace ZeroLevel.ML.LocationMath
{
public static class ViewMath
{
public static GeoPoint[] CalculateCornerGeopoints(CameraMath camera, GeoPoint center, double flightYaw)
{
// True North direction
var bearing = GeoMath.YawToBearing(flightYaw);
// Distances in meters
var imageWidthInMeters = camera.CaclulateImageWidth(center.Altditude);
var imageHeightInMeters = camera.CaclulateImageHeight(center.Altditude);
var diagonalInMeters = Math.Sqrt(imageWidthInMeters * imageWidthInMeters + imageHeightInMeters * imageHeightInMeters);
var distanceInMeters = diagonalInMeters * 0.5d;
// Directions to corners
var topLeftDirection = GeoMath.YawToBearing(bearing - camera.VerticalToDiagonalAngleOffset);
var topRightDirection = GeoMath.YawToBearing(bearing + camera.VerticalToDiagonalAngleOffset);
var bottomLeftDirection = GeoMath.YawToBearing(bearing + 180d + camera.VerticalToDiagonalAngleOffset);
var bottomRightDirection = GeoMath.YawToBearing(bearing + 180d - camera.VerticalToDiagonalAngleOffset);
// Corners locations
var topLeft = center.CalculateDestinationPoint(distanceInMeters, topLeftDirection);
var topRight = center.CalculateDestinationPoint(distanceInMeters, topRightDirection);
var bottomRight = center.CalculateDestinationPoint(distanceInMeters, bottomRightDirection);
var bottomLeft = center.CalculateDestinationPoint(distanceInMeters, bottomLeftDirection);
return new[] { topLeft, topRight, bottomRight, bottomLeft };
}
public static GeoPoint CalculateBoxGeopoint(CameraMath camera, GeoPoint center, double flightYaw, Point2D point)
{
var dx = Math.Abs(camera.ImageWidth * 0.5 - point.x);
var dy = Math.Abs(camera.ImageHeight * 0.5 - point.y);
// Если точка находится вблизи центра снимка, нет смысла считать смещение
if (dx < 10f && dy < 10f)
{
return center;
}
// Переход в 0; 0
var xn = point.x - camera.ImageWidth * 0.5;
if (Math.Abs(xn) < double.Epsilon)
{
xn = 0.000001;
}
var yn = camera.ImageHeight * 0.5 - point.y;
var distanceToPointInPixels = Math.Sqrt(dx * dx + dy * dy);
// Точка на окружности вертикально вверх
var x0 = 0;
var y0 = distanceToPointInPixels;
var angle = GetAngle(x0, y0, xn, yn);
var bearing = GeoMath.YawToBearing(flightYaw);
var bearingToPoint = GeoMath.YawToBearing(bearing + angle);
// рассчитать расстояние и пеленг бокса относительно центральной точки
var distanceInMeters = camera.PixToMeters(center.Altditude, distanceToPointInPixels);
return center.CalculateDestinationPoint(distanceInMeters, bearingToPoint);
}
/// <summary>
/// Угол между двумя отрезками, с общей точкой в 0;0
/// </summary>
private static double GetAngle(double x0, double y0, double x2, double y2)
{
var x1 = 0;
var y1 = 0;
var a1 = -(Math.Atan2(y0 - y1, x0 - x1) * 180 / Math.PI - 90);
var a2 = -(Math.Atan2(y2 - y1, x2 - x1) * 180 / Math.PI - 90);
return (a2 - a1);
}
}
}

Powered by TurnKey Linux.