cocos2dx 仿射变换
AffineTransform __CCAffineTransformMake(float a, float b, float c, float d, float tx, float ty)
{
AffineTransform t;
t.a = a; t.b = b; t.c = c; t.d = d; t.tx = tx; t.ty = ty;
return t;
}
Vec2 __CCPointApplyAffineTransform(const Vec2& point, const AffineTransform& t)
{
Vec2 p;
p.x = (float)((double)t.a * point.x + (double)t.c * point.y + t.tx);
p.y = (float)((double)t.b * point.x + (double)t.d * point.y + t.ty);
return p;
}
Vec2 PointApplyTransform(const Vec2& point, const Mat4& transform)
{
Vec3 vec(point.x, point.y, 0);
transform.transformPoint(&vec);
return Vec2(vec.x, vec.y);
}
Size __CCSizeApplyAffineTransform(const Size& size, const AffineTransform& t)
{
Size s;
s.width = (float)((double)t.a * size.width + (double)t.c * size.height);
s.height = (float)((double)t.b * size.width + (double)t.d * size.height);
return s;
}
AffineTransform AffineTransformMakeIdentity()
{
return __CCAffineTransformMake(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
}
extern const AffineTransform AffineTransformIdentity = AffineTransformMakeIdentity();
const AffineTransform AffineTransform::IDENTITY = AffineTransformMakeIdentity();
//获取仿射变换转换之后的坐标
Rect RectApplyAffineTransform(const Rect& rect, const AffineTransform& anAffineTransform)
{
//四个最值
float top = rect.getMinY(); //左上角Y
float left = rect.getMinX(); //左上角X
float right = rect.getMaxX(); //右下角X
float bottom = rect.getMaxY(); //右下角Y
//四个顶点坐标
Vec2 topLeft = PointApplyAffineTransform(Vec2(left, top), anAffineTransform); //左上角
Vec2 topRight = PointApplyAffineTransform(Vec2(right, top), anAffineTransform); //右上角
Vec2 bottomLeft = PointApplyAffineTransform(Vec2(left, bottom), anAffineTransform); //左下角
Vec2 bottomRight = PointApplyAffineTransform(Vec2(right, bottom), anAffineTransform); //右下角
//找到可以承载这个矩形的最大正矩形坐标
float minX = min(min(topLeft.x, topRight.x), min(bottomLeft.x, bottomRight.x));
float maxX = max(max(topLeft.x, topRight.x), max(bottomLeft.x, bottomRight.x));
float minY = min(min(topLeft.y, topRight.y), min(bottomLeft.y, bottomRight.y));
float maxY = max(max(topLeft.y, topRight.y), max(bottomLeft.y, bottomRight.y));
//返回可容纳最大矩形的Rect
return Rect(minX, minY, (maxX - minX), (maxY - minY));
}
//直接获取坐标
Rect RectApplyTransform(const Rect& rect, const Mat4& transform)
{
//四个最值
float top = rect.getMinY();
float left = rect.getMinX();
float right = rect.getMaxX();
float bottom = rect.getMaxY();
//四个顶点坐标
Vec3 topLeft(left, top, 0);
Vec3 topRight(right, top, 0);
Vec3 bottomLeft(left, bottom, 0);
Vec3 bottomRight(right, bottom, 0);
transform.transformPoint(&topLeft);
transform.transformPoint(&topRight);
transform.transformPoint(&bottomLeft);
transform.transformPoint(&bottomRight);
//获取四个最值点
float minX = min(min(topLeft.x, topRight.x), min(bottomLeft.x, bottomRight.x));
float maxX = max(max(topLeft.x, topRight.x), max(bottomLeft.x, bottomRight.x));
float minY = min(min(topLeft.y, topRight.y), min(bottomLeft.y, bottomRight.y));
float maxY = max(max(topLeft.y, topRight.y), max(bottomLeft.y, bottomRight.y));
//返会可容纳的最大矩形
return Rect(minX, minY, (maxX - minX), (maxY - minY));
}
// [ 1 0 0 ]
//[x y 1]* [ 0 1 0 ]
// [ tx ty 1 ]
//平移到(x+tx, y+ty, 1)
AffineTransform AffineTransformTranslate(const AffineTransform& t, float tx, float ty)
{
return __CCAffineTransformMake(t.a, t.b, t.c, t.d, t.tx + t.a * tx + t.c * ty, t.ty + t.b * tx + t.d * ty);
}
// [ a*sx 0 0 ]
//[x y 1]* [ 0 d*sy 0 ]
// [ 0 0 1 ]
//x坐标缩放sx倍,y坐标缩放sy倍
AffineTransform AffineTransformScale(const AffineTransform& t, float sx, float sy)
{
return __CCAffineTransformMake(t.a * sx, t.b * sx, t.c * sy, t.d * sy, t.tx, t.ty);
}
// [ cosa sina 0 ]
//[x y 1]* [ -sina cosa 0 ]
// [ 0 0 1 ]
//旋转
AffineTransform AffineTransformRotate(const AffineTransform& t, float anAngle)
{
float sine = sinf(anAngle);
float cosine = cosf(anAngle);
return __CCAffineTransformMake( t.a * cosine + t.c * sine,
t.b * cosine + t.d * sine,
t.c * cosine - t.a * sine,
t.d * cosine - t.b * sine,
t.tx,
t.ty);
}
//将两个矩阵相乘 得到第二个矩阵的xy轴在第一个矩阵xy轴上的投影
//下面的参数化简完就变成了
//[ a1*a2 0 0 ]
//[ 0 d1*d2 0 ]
//[ 0 0 0 ]
/* Concatenate `t2' to `t1' and return the result:
t' = t1 * t2 */
AffineTransform AffineTransformConcat(const AffineTransform& t1, const AffineTransform& t2)
{
return __CCAffineTransformMake( t1.a * t2.a + t1.b * t2.c, t1.a * t2.b + t1.b * t2.d, //a,b
t1.c * t2.a + t1.d * t2.c, t1.c * t2.b + t1.d * t2.d, //c,d
t1.tx * t2.a + t1.ty * t2.c + t2.tx, //tx
t1.tx * t2.b + t1.ty * t2.d + t2.ty); //ty
}
Mat4 TransformConcat(const Mat4& t1, const Mat4& t2)
{
return t1 * t2;
}
//
/* Return true if `t1' and `t2' are equal, false otherwise. */
bool AffineTransformEqualToTransform(const AffineTransform& t1, const AffineTransform& t2)
{
return (t1.a == t2.a && t1.b == t2.b && t1.c == t2.c && t1.d == t2.d && t1.tx == t2.tx && t1.ty == t2.ty);
}
//交换xy轴的值
//转换为
//[ d 0 0 ]
//[ 0 a 0 ]
//[ 0 0 0 ]
AffineTransform AffineTransformInvert(const AffineTransform& t)
{
float determinant = 1 / (t.a * t.d - t.b * t.c);
return __CCAffineTransformMake(determinant * t.d, -determinant * t.b, -determinant * t.c, determinant * t.a,
determinant * (t.c * t.ty - t.d * t.tx), determinant * (t.b * t.tx - t.a * t.ty) );
}
NS_CC_END
如果不明白为什么一些原理,比如tx=ty=0,可以看一下下面这篇文章,有很细致的讲解,我这个是只是对代码的解读。
仿射变换几何讲解
cocos2dx 仿射变换的更多相关文章
- cocos2dx骨骼动画Armature源码分析(三)
代码目录结构 cocos2dx里骨骼动画代码在cocos -> editor-support -> cocostudio文件夹中,win下通过筛选器,文件结构如下.(mac下没有分,是整个 ...
- [原创]cocos2d-x研习录-第二阶 概念类之精灵类(CCSprite)
上一节说布景层CCLayer是小容器,那么精灵类CCSprite就是容器添加的内容,它是构成游戏的主要元素.精灵这个名称应该是游戏专用,它表示游戏中玩家操作的主角.敌人.NPC(Non Player ...
- [置顶] COcos2d-X 中文API
本文来自http://blog.csdn.net/runaying ,引用必须注明出处! COcos2d-X 中文API 温馨提醒:使用二维码扫描软件,就可以在手机上访问我的博客啦!另外大家可以访问另 ...
- Cocos2D-x权威指南: CCNode类方法:
5.1.4 画图节点CCNode和图层CCLayer CCNode中提供的方法,在public块中的方法主要有下面几个部分: 1.针对节点显示的属性信息读写 2.针对节点变换的属性信息读写 3.针对子 ...
- Cocos2D-X扫盲之坐标系、锚点
一.引言 在Cocos2D-X的开发过程中,经常会碰到设置精灵位置的问题.而设置位置的过程,涉及到两个问题:第一是坐标系,包括原点的位置.X/Y坐标轴的方向灯:第二是基准点(Cocos2D-X中叫锚点 ...
- cocos2dx调用浏览器打开网址
安卓端cocos2dx/platform/android路径下CCApplication.h: virtual void openURL(const char* pszUrl); CCApplicat ...
- 使用“Cocos引擎”创建的cpp工程如何在VS中调试Cocos2d-x源码
前段时间Cocos2d-x更新了一个Cocos引擎,这是一个集合源码,IDE,Studio这一家老小的整合包,我们可以使用这个Cocos引擎来创建我们的项目. 在Cocos2d-x被整合到Cocos引 ...
- Cocos2d-x不要随便在onEnter里面addChild
使用任何版本的Cocos2d-x(1.x,2.x,3.0),在onEnter中调用addChild,都要小心谨慎,因为它有可能导致两种莫名其妙的BUG,莫名其妙的BUG当然难以定位了!更何况这个BUG ...
- 通过Matrix进行二维图形仿射变换
Affine Transformation是一种二维坐标到二维坐标之间的线性变换,保持二维图形的"平直性"和"平行性".仿射变换可以通过一系列的原子变换的复合来 ...
随机推荐
- 模板—Kruskal
int getf(int x){return (f[x]==x)?x:f[x]=getf(f[x]);} void hb(int x,int y){x=getf(x),y=getf(y),f[y]=x ...
- 屏蔽指定地区IP访问
<?php if ($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]) { $ip = $HTTP_SERVER_VARS["HT ...
- 20182019-acmicpc-asia-dhaka-regional F .Path Intersection 树链剖分
直接进行树链剖分,每次对路径区间内的所有点值+1,线段树进行维护,然后查询线段树的最大值的个数!!! 查询线段树区间最大值个数,可以先维护区间和,在维护区间最值,如果区间和等于区间最值乘以区间长度,那 ...
- Remove Extra One 权值线段树
最近疯狂练习线段树... 这道题题意很简单,在1-n中,找寻一个数,使得去掉这个数后,对于每个位置中满足 1<=j<i && a[ j ]<a[ i ] 的位置尽可能 ...
- 强连通分量-----Kosaraju
芝士: 有向图强连通分量在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connect ...
- JSX语法及特点介绍
1.1 基本语法 1)自定义组件名首字母大写:元素名即组件名,首字母需要大写.首字母小写时React会以为这是HTML的标准标签,因此自定义的组件名需要首字母大写,否则会报错. 2)嵌套:在rende ...
- 微信接口开发报错invalid credential, access_token is invalid or not latest hint
微信接口凭证access_token一定要全局管理 我们的查酒后台集成了微信公众平台的客服API接口,不用登录微信公众号的后台就可以直接给用户发送消息.最近,运营的同事反馈,通过微信查酒,后台无法直接 ...
- windonws卸载已安装opencv,安装新版本
主要步骤: 步骤一:卸载opencv-python(如果还有安装opencv-contrib-python,也需要卸载) 步骤二:安装新的opencv-python及opencv-contrib-py ...
- [转载] linux、Solaris下xdmcp远程桌面服务
原文链接 http://youlvconglin.blog.163.com/blog/static/52320420106243857254/ 使用图形界面远程登录linux和Solaris,首先要在 ...
- python编程之操作系统基础
操作系统发展史: 最早的计算机没有操作系统的概念:是使用打孔机和打孔卡片来进行计算的.只能一个一个处理. 后来产生了批处理系统,可以批量处理,进而加快计算的速度. 批处理系统:串行 数据处理速度加快 ...