I'm trying to convert (longitude/latitude) locations to rectangles on a phone screen. But for now let's pretend they're normal points on Oxy plane.
Assume the camera is standing at point (X,Y)
, corresponing to the center of the phone screen. It's pointing in direction (vx,vy)
, it has 60 degree cone of vision (30 degree clockwise and 30 degree counter-clockwise). The camera direction can rotate freely, so vx, vy in [-1 -> 1]
.
There's a list of N
point (x[], y[])
, each represents a location.
At each step, all points that are inside the cone of vision is selected, call them (px[], py[])
. This step is simple. Next, I need to draw (px[], py[])
on the phone screen. The biggest problem is when the camera + two points are collinear. I have zero idea of how to handle this. Edit: both points must be shown on screen, so maybe adding some random offset?
Given the camera position, camera looking direction, and a point px[i], py[i]
, what's its pixel coordinate on the screen? If there's not enough information, then whatever method that can handle the collinear situation is okay.
Edit:
Image 1 shows an example. Given the points + camera position/direction, points 1,2,3,4 are in vision. Then, they are shown on the screen as in image 2.
Possible solution for 2D (no illusion of 3D on the screen):
Horizontal position: use the angle from the camera's direction to determine whether its on the left/right side of the screen. Normalize the angles using the biggest angle. The normalized angle (0->1) is used to determine how far to the left/right that point is, where normAngle = 0
means it's at the middle of the screen, and normAngle = 1
means it's at the leftest/rightest pixel of the screen.
Vertical position: Same as above but use normalized distance from camera instead of angle from camera direction.
Is there a better way?
You can map value point_angle-central_angle
onto -Pi/2..Pi/2 (-90..90)
range (assuming zero angle is directed top at the screen), so use polar coordinates with some distortion.
rho = (px - camx)^2 + (py - camy)^2
point_angle = atan2(py - camy, px - camx)
deviation = point_angle - cam_angle
screen_rho = somefunction(rho)
//in simple case just coefficent C*rho to provide proper distance in screen limits
screen_angle = 3 * deviation //-30 =>-90
screen_x = screen_rho * cos(screen_angle)
screen_y = screen_rho * sin(screen_angle)