GVKun编程网logo

关于cocos2d中的世界坐标与局部坐标(cocos坐标系)

10

如果您想了解关于cocos2d中的世界坐标与局部坐标和cocos坐标系的知识,那么本篇文章将是您的不二之选。我们将深入剖析关于cocos2d中的世界坐标与局部坐标的各个方面,并为您解答cocos坐标系

如果您想了解关于cocos2d中的世界坐标与局部坐标cocos坐标系的知识,那么本篇文章将是您的不二之选。我们将深入剖析关于cocos2d中的世界坐标与局部坐标的各个方面,并为您解答cocos坐标系的疑在这篇文章中,我们将为您介绍关于cocos2d中的世界坐标与局部坐标的相关知识,同时也会详细的解释cocos坐标系的运用方法,并给出实际的案例分析,希望能帮助到您!

本文目录一览:

关于cocos2d中的世界坐标与局部坐标(cocos坐标系)

关于cocos2d中的世界坐标与局部坐标(cocos坐标系)

一、
主要的接口函数为以下四个:
convertToNodeSpace(); //转换成局部坐标
convertToNodeSpaceAR();
convertToWorldspace(); //转换成世界坐标
convertToWorldspaceAR();

注:通常做游戏是放置精灵所用的坐标是世界坐标,即以场景左下角为原点的坐标系
二、
简单来说,假设图中一个精灵为child,鼠标在图中点击的位置是point:
Vec2 pos=child->convertToNodeSpace(point) ;
此时pos的位置坐标以child左下角为原点坐标系的坐标

Vec2 pos=child->convertToNodeSpaceAR(point) ;
此时pos的位置坐标以child锚点为原点坐标系的坐标,child锚点默认情况下是Vec2(0.5,0.5)

Vec2 pos=child->convertToWorldspace(point) ;
此时pos的位置坐标是以child左下角世界坐标为原点后的坐标系,举个例子,child->convertToWorldspace(Vec2(0,0))时,最后得出的坐标就是child原来世界坐标系中左下角的坐标。
简单的说,pos坐标是child左下角世界坐标系与point世界坐标系的和

Vec2 pos=child->convertToWorldspaceAR(point) ;
同理:pos坐标是child锚点的世界坐标系与point世界坐标系的和

另加:
Director::getInstance()->converttoGL(); //转换成openGL坐标
Director::getInstance()->converttoUI(); //转换成UI坐标

cocos默认的是使用openGL坐标,即坐标原点在左下角 而UI坐标的坐标原点在左上角

2.cocos2d-x坐标体系(UI坐标系,GL坐标系,本地坐标,世界坐标,节点坐标)

2.cocos2d-x坐标体系(UI坐标系,GL坐标系,本地坐标,世界坐标,节点坐标)


  1. openGL & UI坐标体系

OpenGL坐标系:该坐标原点在屏幕左下角,x轴向右,y轴向上。这也就是cocos2dx中用到的坐标系。

屏幕坐标系:该坐标系的原点在屏幕左上角,x轴向右,y轴向下,其实和OpenGL坐标系的差别也就是y轴的方向。假设游戏场景的分辨率为(500500),其中一个点坐标为(200,200),那么它在OpenGL坐标系中的坐标还是(200,200),在屏幕坐标系中则倒过来,则为(200500-200)。其实也就是69的差别。

图: UI坐标系

图: GL坐标系

2 转化函数

CCDirector::sharedDirector()->convertToUI();

CCDirector::sharedDirector()->convertToGL();

节点坐标系:又名相对坐标系,本地坐标,和OpenGL坐标系方向一致,不同的是原点的父节点左下角。

世界坐标系:又名绝对坐标系,世界即指游戏世界,我们只要知道世界坐标系和OpenGL坐标系方向一致,原点在屏幕左下角,x轴向右,y轴向上。

节点坐标与世界坐标转化

几乎所有的游戏引擎都会使用本地坐标系而非世界坐标系来指定元素

的位置,这样做的好处是当计算物体运动的时候使用同一本地坐标系的元素

可以作为一个子系统独立计算,最后再加上坐标系的运动即可,这是物理研

究中常用的思路。例如一个在行驶的车厢内上下跳动的人,我们只需要在每

帧绘制的时候计算他在车厢坐标系中的位置,然后加上车的位置就可以计算

出人在世界坐标系中的位置,如果使用单一的世界坐标系,人的运动轨迹就

变复杂了。

3 关于坐标体系的案例:

Coordinate.h

#ifndef __COORDINATE_H__

#define __COORDINATE_H__

#include "cocos2d.h"

USING_NS_CC;

//坐标体系

class Coordinate :public cclayer

{

public:

static CCScene * scene();

CREATE_FUNC(Coordinate);

bool init();

//触摸事件开始的一个事件,第二个参数只是为了做苹果的兼容才保留的

virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);

};

#endif

Coordinate.cpp

#include "Coordinate.h"

#include "AppMacros.h"

CCScene * Coordinate::scene() {

scene = CCScene::create();

Coordinate * layer = create();

scene->addChild(layer);

return scene;

}

bool init()

{

cclayer::init();

//打开触摸开关

setTouchEnabled(true);

//下面的kCCtouchesOneByOne是一个枚举:

//typedef enum {

// kCCtouchesAllAtOnce,

// kCCtouchesOneByOne,

//} cctouchesMode;

setTouchMode(kCCtouchesOneByOne);

//创建一个精灵

CCSprite *big = CCSprite::create();

big->setColor(ccRED);

//设置锚点

big->setAnchorPoint(ccp(0,0));

//表示的是一个矩形,CCRectMake是一个宏

big->setTextureRect(CCRectMake(0,150,150));

big->setPosition(ccp(100,100));

addChild(big);

CCSprite *little = create();

little->setColor(ccYELLOW);

little->

little->

little->

//从下面可以知道一个精灵中可以添加另外一个精灵

big->addChild(little);

cclog("little x = %f,y = %f",little->getPositionX(),0); font-family:新宋体; font-size:9.5pt">getPositionY());

CCPoint toWorld = big->convertToWorldspace(little->getPosition());

"toWorld x = %f,y=%f",toWorld.x,toWorld.y);

CCSprite *little2 = create();

little2->setColor(ccGREEN);

little2->

little2->

little2->

addChild(little2);

CCPoint toNode = big->convertToNodeSpace(little2->"little2 x = %f,little2->getPositionY());

"toNode x = %f,toNode.x,toNode.y);

CCMoveBy *by = CCMoveBy::create(2,ccp(200,0));

CCMoveBy *by2 = (CCMoveBy *)by->reverse();

//最后一个NULL是一个哨兵

CCSequence *seq = CCSequence::create(by,by2,138); font-family:新宋体; font-size:9.5pt">NULL);

big->runAction(CCRepeatForever::create(seq));

//第一个参数是:duration

//第二个参数是:移动位置.表示上下移动

CCMoveBy *lby =

CCMoveBy *lby2 = (CCMoveBy *)lby->reverse();

CCSequence *lseq = create(lby,lby2,138); font-family:新宋体; font-size:9.5pt">NULL);

little->create(lseq));

return true;

}

//触摸事件开始

bool CCEvent *pEvent)

{

"ccTouchBegan");

//基于OpenGL的世界坐标

CCPoint pGl = pTouch->getLocation();

"GL:x = %f,pGl.x,pGl);

//基于UI屏幕的坐标

CCPoint pUi = pTouch->getLocationInView();

"UI:x = %f,pUi.x,pUi.y);

//将基于GL的坐标转换成为UI的屏幕坐标

CCPoint toUi = CCDirector::sharedDirector()->convertToUI(pGl);

"ToUix = %f,toUi.x,toUi.y);

//将屏幕坐标的转换成为本地坐标

CCPoint toGL = convertToGL(pUi);

"ToGLx = %f,toGL.x,toGL.y);

//转换成节点坐标

CCPoint node = this->convertToNodeSpace(pGl);

"Node:x = %f,node.x,node.y);

return false;

}

运行结果:

<cocos2dx 随记> 关于cocos2dx接Android sdk的一些坑

关于cocos2dx接Android sdk的一些坑

简单说说UI线程 :在Android中,有个非常重要的家伙非常霸道,那就是UI线程。这霸道之一:不能被阻塞。 之二:系统对每一个组件的调用都从UI线程分发出去。

简单说说openGL线程:但凡cocos2dx 启动的绘制线程都是openGL线程。就这么多


任何SDK界面的调用,必须从UI线程中调用,所以需要放到主线程中。如果我们直接从GL线程中调用,轻则调用不了,重者程序蹦死。

解决办法:

得到主线程的handler,这里简单说一种,就是在onCreate中new一个静态handler。

或者new Handler(Looper.getMainLooper()),且叫mainHandler吧,

启动一个线程,

			Thread sendThread=new Thread(new Runnable(){
				public void run() {
					mainHandler.post(sendRun);
				}
			});

	public Runnable sendRun=new Runnable() {
		@Override
		public void run() {
//			//这里就可以调用sdk里面的东西了
	}
};	
</pre><pre name="code"><span>如何从UI线程中调用OpenGL线程呢,直接调用,我以前也干过,感觉没什么问题被发现(he he),如果发现了问题我觉得还是这么调用的好</span>
</pre><pre name="code">Cocos2dxGLSurfaceView.getInstance().queueEvent(new Runnable() {
			public void run() {
<span>				</span>//回调什么马的
			}
		});
至于想知道,jni native什么的 还请出门右拐,不送

c – 使用z = 0将2D图像坐标转换为3D世界坐标

c – 使用z = 0将2D图像坐标转换为3D世界坐标

> OpenCV => 3.2
>操作系统/平台=> Windows 64位
>编译器=> Visual Studio 2015

我目前正在研究我的项目,该项目涉及车辆检测和跟踪以及估计和优化车辆周围的长方体.为此,我完成了车辆的检测和跟踪,我需要找到车辆边界框边缘图像点的三维世界坐标,然后估算长方体和项目边缘的世界坐标.它回到图像显示它.

所以,我是计算机视觉和OpenCV的新手,但据我所知,我只需要在图像上需要4个点,并且需要知道这4个点的世界坐标,并在OpenCV中使用solvePNP来获取旋转和平移向量(我已经有相机矩阵和失真系数).然后,我需要使用Rodrigues将旋转矢量转换为旋转矩阵,然后将其与平移矢量连接以获得我的外在矩阵,然后将外部矩阵与相机矩阵相乘以得到我的投影矩阵.由于我的z坐标为零,所以我需要从投影矩阵中取出第三列,该矩阵给出用于将2D图像点转换为3D世界点的单应矩阵.现在,我找到了单应矩阵的逆矩阵,它给出了3D世界点到2D图像点之间的单应性.之后,我将图像点[x,y,1] t与逆单应矩阵相乘得到[wX,wY,w] t,并将整个向量除以标量w得到[X,Y,1]给我世界坐标的X和Y值.

我的代码看起来像这样:

#include "opencv2/opencv.hpp"
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <math.h> 
#include <conio.h>

using namespace cv;
using namespace std;

Mat cameraMatrix,distCoeffs,rotationVector,rotationMatrix,translationVector,extrinsicMatrix,projectionMatrix,homographyMatrix,inverseHomographyMatrix;


Point point;
vector<Point2d> image_points;
vector<Point3d> world_points;

int main()
{
FileStorage fs1("intrinsics.yml",FileStorage::READ);

fs1["camera_matrix"] >> cameraMatrix;
cout << "Camera Matrix: " << cameraMatrix << endl << endl;

fs1["distortion_coefficients"] >> distCoeffs;
cout << "distortion Coefficients: " << distCoeffs << endl << endl;



image_points.push_back(Point2d(275,204));
image_points.push_back(Point2d(331,308));
image_points.push_back(Point2d(275,308));

cout << "Image Points: " << image_points << endl << endl;

world_points.push_back(Point3d(0.0,0.0,0.0));
world_points.push_back(Point3d(1.775,4.620,0.0));
world_points.push_back(Point3d(0.0,0.0));

cout << "World Points: " << world_points << endl << endl;

solvePnP(world_points,image_points,cameraMatrix,translationVector);
cout << "Rotation Vector: " << endl << rotationVector << endl << endl;
cout << "Translation Vector: " << endl << translationVector << endl << endl;

Rodrigues(rotationVector,rotationMatrix);
cout << "Rotation Matrix: " << endl << rotationMatrix << endl << endl;

hconcat(rotationMatrix,extrinsicMatrix);
cout << "Extrinsic Matrix: " << endl << extrinsicMatrix << endl << endl;

projectionMatrix = cameraMatrix * extrinsicMatrix;
cout << "Projection Matrix: " << endl << projectionMatrix << endl << endl;

double p11 = projectionMatrix.at<double>(0,0),p12 = projectionMatrix.at<double>(0,1),p14 = projectionMatrix.at<double>(0,3),p21 = projectionMatrix.at<double>(1,p22 = projectionMatrix.at<double>(1,p24 = projectionMatrix.at<double>(1,p31 = projectionMatrix.at<double>(2,p32 = projectionMatrix.at<double>(2,p34 = projectionMatrix.at<double>(2,3);


homographyMatrix = (Mat_<double>(3,3) << p11,p12,p14,p21,p22,p24,p31,p32,p34);
cout << "Homography Matrix: " << endl << homographyMatrix << endl << endl;

inverseHomographyMatrix = homographyMatrix.inv();
cout << "Inverse Homography Matrix: " << endl << inverseHomographyMatrix << endl << endl;

Mat point2D = (Mat_<double>(3,1) << image_points[0].x,image_points[0].y,1);
cout << "First Image Point" << point2D << endl << endl;

Mat point3Dw = inverseHomographyMatrix*point2D;
cout << "Point 3D-W : " << point3Dw << endl << endl;

double w = point3Dw.at<double>(2,0);
cout << "W: " << w << endl << endl;

Mat matPoint3D;
divide(w,point3Dw,matPoint3D);

cout << "Point 3D: " << matPoint3D << endl << endl;

_getch();
return 0;

我已经获得了四个已知世界点的图像坐标,并对其进行了硬编码以简化. image_points包含四个点的图像坐标,world_points包含四个点的世界坐标.我正在考虑第一个世界点作为世界轴的原点(0,0)并使用已知距离计算其他四个点的坐标.现在在计算逆单应矩阵之后,我将其与[image_points [0] .x,image_points [0] .y,1] t相乘,其与世界坐标(0,0)相关.然后我将结果除以第三个分量w得到[X,1].但是在打印出X和Y的值之后,事实证明它们分别不是0,0.怎么了?

我的代码输出如下:

Camera Matrix: [517.0036881709533,320;
0,517.0036881709533,212;
0,1]

distortion Coefficients: [0.1128663679798094;
-1.487790079922432;
0;
0;
2.300571896761067]

Image Points: [275,204;
331,308;
275,308]

World Points: [0,0;
1.775,4.62,0;
0,0]

Rotation Vector:
[0.661476468596541;
-0.02794460022559267;
0.01206996342819649]

Translation Vector:
[-1.394495345140898;
-0.2454153722672731;
15.47126945512652]

Rotation Matrix:
[0.9995533907649279,-0.02011656447351923,-0.02209848058392758;
 0.002297501163799448,0.7890323093017149,-0.6143474069013439;
 0.02979497438726573,0.6140222623910194,0.7887261380159]

Extrinsic Matrix:
[0.9995533907649279,-0.02209848058392758,-1.394495345140898;
 0.002297501163799448,-0.6143474069013439,-0.2454153722672731;
 0.02979497438726573,0.7887261380159,15.47126945512652]

Projection Matrix:
[526.3071813531748,186.086785938988,240.9673682002232,4229.846989065414;
7.504351145361707,538.1053336219271,-150.4099339268854,3153.028471890794;
0.02979497438726573,15.47126945512652]

Homography Matrix:
[526.3071813531748,15.47126945512652]

Inverse Homography Matrix:
[0.001930136511648154,-8.512427241879318e-05,-0.5103513244724983;
-6.693679705844383e-06,0.00242178892313387,-0.4917279870709287
-3.451449134581896e-06,-9.595179260534558e-05,0.08513443835773901]

First Image Point[275;
204;
1]

Point 3D-W : [0.003070864657310213;
0.0004761913292736786;
0.06461112415423849]

W: 0.0646111
Point 3D: [21.04004290792539;
135.683117651025;
1]

解决方法

你的推理是合理的,但你在最后一个部门犯了一些错误……或者我错过了什么?

W师之前的结果是:

Point 3D-W : 
[0.003070864657310213;
0.0004761913292736786;
0.06461112415423849]

现在我们需要通过将所有坐标除以W(数组的第3个元素)来对其进行标准化,如您在问题中所述.所以:

Point 3D-W normalized = 
[0.003070864657310213 / 0.06461112415423849;
0.0004761913292736786 / 0.06461112415423849;
0.06461112415423849 / 0.06461112415423849]

结果如下:

Point 3D-W normalized = 
[0.047528420183179314;
 0.007370113668614144;
 1.0]

这该死的接近于[0,0].

Cocos-2d 坐标系及其坐标转换

Cocos-2d 坐标系及其坐标转换



原作者:jlins 出处:博客园http://www.cnblogs.com/dyllove98/p/3231175.html

Cocos-2d中,涉及到4种坐标系:

GL坐标系Cocos2DOpenglES为图形库,所以它使用OpenglES坐标系。GL坐标系原点在屏幕左下角x轴向右,y轴向上。

屏幕坐标系苹果的Quarze2D使用的是不同的坐标系统,原点在屏幕左上角x轴向右,y轴向下。ios的屏幕触摸事件CCTouch传入的位置信息使用的是该坐标系。因此在cocos2d中对触摸事件做出响应前需要首先把触摸点转化到GL坐标系。可以使用CCDirectorconvertToGL来完成这一转化。

世界坐标系也叫做绝对坐标系。世界坐标系和GL坐标系一致,原点在屏幕左下角。

cocos2d中的元素是有父子关系的层级结构,我们通过CCNodeposition设定元素的位置使用的是相对与其父节点的本地坐标系而非世界坐标系。最后在绘制屏幕的时候cocos2d会把这些元素的本地坐标映射成世界坐标系坐标。)

本地坐标系本地坐标系也叫做物体坐标系,是和特定物体相关联的坐标系。每个物体都有它们独立的坐标系,当物体移动或改变方向时,和该物体关联的坐标系将随之移动或改变方向。比如用cocos2d-x创建了个矩形colorLayer:CCRect(10,10,100,100),这是的本地坐标系为以(10,10)为坐标原点,x轴向右,y轴向上。如果创建了一个CCSprite,锚点为(0.5,0.5),位置为(100,100),size为(40,40),这时的本地坐标系为以(80,80)为坐标原点,x轴向右,y轴向上。

Cocos-2d中,坐标系转换:

CCPointconvertToNodeSpace(constCCPoint& worldPoint);
CCPoint convertToWorldspace(const CCPoint& nodePoint);
CCPoint convertToNodeSpaceAR(const CCPoint& worldPoint);
CCPoint convertToWorldspaceAR(const CCPoint& nodePoint);

1.CCPointconvertToNodeSpace(constCCPoint& worldPoint);

CGPointnodeSpace =[spriteParentconvertToNodeSpace:orignPosition];

orignPosition转换为相对于spriteParent的本地坐标

2.CCPointconvertToWorldspace(const CCPoint& nodePoint);

CGPointwordeSpace =[spriteParentconvertToWorldspace:orignPosition];

orignPosition转换为相对于spriteParent的世界坐标

3.CCPointconvertToNodeSpaceAR(const CCPoint& worldPoint);

CGPointnodeSpaceAR =[spriteParentconvertToWorldspace:orignPosition];

spriteParent的坐标系原点设置在spriteParent的锚点位置

然后 orignPosition转换为相对于spriteParent的本地坐标

4.CCPointconvertToWorldspaceAR(const CCPoint& nodePoint);

CGPointwordeSpaceAR =[spriteParentconvertToWorldspace:orignPosition];

spriteParent的坐标系原点设置在spriteParent的锚点位置

然后 orignPosition转换为相对于spriteParent的世界坐标

欢迎关注关东升新浪微博@tony_关东升。

关注智捷课堂微信公共平台,了解最新技术文章、图书、教程信息

更多精品iOSCocos、移动设计课程请关注智捷课堂官方网站:http://www.zhijieketang.com

智捷课堂论坛网站:http://51work6.com/forum.PHP

我们今天的关于关于cocos2d中的世界坐标与局部坐标cocos坐标系的分享已经告一段落,感谢您的关注,如果您想了解更多关于2.cocos2d-x坐标体系(UI坐标系,GL坐标系,本地坐标,世界坐标,节点坐标)、 关于cocos2dx接Android sdk的一些坑、c – 使用z = 0将2D图像坐标转换为3D世界坐标、Cocos-2d 坐标系及其坐标转换的相关信息,请在本站查询。

本文标签: