我正在制作由多点触控控制的交互式地图应用程序。我想在保持触摸下触摸的位置的同时导航地图。我使用透视图,向下朝向地图的摄像机角度永远不会改变。我有移动和旋转工作。通过计算当前触摸和先前触摸的世界坐标(通过在基准平面上投射光线)并且使相机移动相同的距离和方向来移动。通过在触摸点周围旋转相机进行旋转。
现在随着变焦,我有更多的困难。因为当您想要从屏幕上的任意点进行缩放时,您不仅需要向前移动相机,还要向触摸点移动。我有一个近似值,但它不是很准确,并且不能很好地扩展。有没有办法准确计算摄像机位置,以便您缩放的点保持在相同的屏幕坐标上?
我使用Unity3D(C#用于编写脚本)。这是我的代码的一些例子。
Vector3 prevposition1; // Screen coordinates of previous touch1
Vector3 nowposition1; // Screen coordinates of touch1 now
Vector3 prevposition2; // Screen coordinates of previous touch2
Vector3 nowposition2; // Screen coordinates of touch2 now
Vector3 prevhitpoint1; // World coordinates of previous touch1 on plane
Vector3 prevhitpoint2; // World coordinates of previous touch2 on plane
Vector3 nowhitpoint1; // World coordinates of touch1 on plane
Vector3 nowhitpoint2; // World coordinates of touch2 on plane
void RotateMap()
{
transform.RotateAround(nowhitpoint1, Vector3.up, Mathf.Rad2Deg * -(prevAngle - nowAngle));
}
void MoveOverMap()
{
Vector3 direction = nowhitpoint1 - prevhitpoint1;
direction = direction * -1f;
if (prevhitpoint1 != new Vector3(-1,-1,-1))
{
transform.position = transform.position + direction;
} else
{
transform.position = transform.position;
}
}
void ZoomMap()
{
//Calculate direction from center
RaycastHit hit1;
int layerMask = 1 << 8;
Ray ray1 = Camera.main.ViewportPointToRay (new Vector3(0.5f,0.5f,0));
if (Physics.Raycast(ray1, out hit1, Mathf.Infinity, layerMask))
{
}
//zoom
Vector3 direction1 = hit1.point - nowhitpoint1;
float distanceToCentersc1 = Vector2.Distance(nowposition1, new Vector2(Screen.width/2,Screen.height/2));
transform.position = transform.position + (nowDistance - prevDistance) * transform.forward * zoomSpeed * Time.deltaTime;
float distanceToCentersc2 = Vector2.Distance(Camera.main.WorldToScreenPoint(nowhitpoint1), new Vector2(Screen.width/2,Screen.height/2));
//adjust position
float distanceRatio = distanceToCentersc1/distanceToCentersc2;
transform.position = transform.position - direction1 * (1-distanceRatio);
}