最近在研究 【高通 AR 】技術,通過其Examples來學習相關SDK。
在研究 ImageTagets 的時候,想獲取:
1、目標空間對應的3D point 對應的 屏幕上2D point ;
2、屏幕上觸碰一點 對應的 空間座標。
雖然其開發文檔:https://developer.vuforia.com/resources/dev-guide/screen-coordinates 對這2個需求進行了實現方式闡述,但是都不是很具體。所以花了不少時間去實現(尤其是需求1)。現將 空間座標 轉換成 屏幕座標的方法總結如下:
Target space to screen space
//xq
- (CGPoint)getScreenPointByPose:(QCAR::Matrix34F)pose
{
// need to account for the orientation on view size
CGFloat viewWidth = self.frame.size.height; // Portrait
CGFloat viewHeight = self.frame.size.width; // Portrait
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsLandscape(orientation))
{
viewWidth = self.frame.size.width;
viewHeight = self.frame.size.height;
}
// calculate any mismatch of screen to video size
QCAR::CameraDevice& cameraDevice = QCAR::CameraDevice::getInstance();
const QCAR::CameraCalibration& cameraCalibration = cameraDevice.getCameraCalibration();
QCAR::VideoMode videoMode = cameraDevice.getVideoMode(QCAR::CameraDevice::MODE_DEFAULT);
CGFloat scale = viewWidth/videoMode.mWidth;
if (videoMode.mHeight * scale < viewHeight)
scale = viewHeight/videoMode.mHeight;
CGFloat scaledWidth = videoMode.mWidth * scale;
CGFloat scaledHeight = videoMode.mHeight * scale;
CGPoint margin = {(scaledWidth - viewWidth)/2, (scaledHeight - viewHeight)/2};
CGPoint center =[self projectCoord:CGPointMake(0,0) inView:cameraCalibration andPose:pose withOffset:margin andScale:scale];
NSLog(@"center = %@",[NSValue valueWithCGPoint:center]);
CGPoint centerNew = center;
centerNew.x = viewHeight - center.y;
centerNew.y = center.x;
NSLog(@"centerNew = %@",[NSValue valueWithCGPoint:centerNew]);
return centerNew;
}
- (CGPoint) projectCoord:(CGPoint)coord inView:(const QCAR::CameraCalibration&)cameraCalibration andPose:(QCAR::Matrix34F)pose withOffset:(CGPoint)offset andScale:(CGFloat)scale
{
CGPoint converted;
QCAR::Vec3F vec(coord.x,coord.y,0);
QCAR::Vec2F sc = QCAR::Tool::projectPoint(cameraCalibration, pose, vec);
converted.x = sc.data[0]*scale - offset.x;
converted.y = sc.data[1]*scale - offset.y;
return converted;
}
其中:方法一中傳入參數 pose
由 - (void)renderFrameQCAR
方法獲取,即被跟蹤到目標的 3*4姿態矩陣。(詳見:https://developer.vuforia.com/resources/dev-guide/pose-matrix-explained),返回值
centerNew 即爲 屏幕上對應的座標。