Cocos2dx-3.2 数学类Vec2/Size/Rect

原文:http://www.jb51.cc/article/p-knqxbngo-wx.html

【唠叨】

数学类Vec2SizeRect,是cocos2dx中比较常用的类。

比如设置图片位置,设置图片大小,两图片的碰撞检测等等。

比起2.x版本,在3.x中本质上其实没有太大的变化,主要的变化就是将全局宏定义相关的操作封装到各自的类中而已。比如:Vec2的向量运算宏定义ccp***(),现在都已经封装到Vec2类里面去了。


【番外】

在V2.x中,底层数学库使用的是:Kazmath数学库

而在V3.1中,由于Sprite3D需要我们提供更多的API给开发者,这是Kazmath库所不能提供的,而cocos2d-x内部拥有多个数学库是没有意义的。

所以V3.1中,底层选择了新的数学库:GamePlay3D数学库


【Vec2】

Vec2原名Point,它既可以表示一个二维坐标点,又可以表示一个二维向量。

同时Vec2对运算符进行了重载,可以很方便的完成Vec2的赋值、加减乘除等操作。另外还有与坐标向量相关的:距离、角度、点积、叉积、投影、标准化等操作。

此外在3.x中,还将2.x里的函数定义ccp***(如ccp,ccpAdd,ccpSub)相关的操作都封装到了这个Vec2的类中,这样就可以更加系统化地管理向量的运算操作了。

此外,除了Vec2。还有两个坐标类:Vec3、Vec4,分别代表了三维、四维坐标向量。

查看2.x与3.x的变化请移步:http://www.jb51.cc/article/p-xltaecax-wx.html

Vec2可以是一个二维坐标点,也可以是一个二维向量。


1、创建方式

/**
 * Vec2只有两个成员变量x,y
 */
    float x; //X坐标
    float y; //Y坐标
 
 
/**
 * 构造函数
 */ 
    Vec2();                                   //(0,0)
    Vec2(float xx,float yy);                 //(xx,yy)
    Vec2(const float* array);                 //(array[0],array[1])
    Vec2(const Vec2& copy);                   //copy
    Vec2(const Vec2& p1,const Vec2& p2);     //p2 - p1

2、设置向量坐标

使用set可以给向量重新设置新坐标值。

void set(float xx,float yy);             //(xx,yy)
    void set(const float* array);             //(array[0],array[1])
    void set(const Vec2& v);                  //v
    void set(const Vec2& p1,const Vec2& p2); //p2 - p1

3、向量运算

其中包含了一些2.x中的ccp***()宏定义的函数,都全部封装到了Vec2类中。

/**
 * 向量运算
 *     void     : 自身运算,值会改变
 *     有返回值 : 返回运算结果,值不会改变
 */
    void add(const Vec2& v);                      //相加( x+v.x,y+v.y )
    void subtract(const Vec2& v);                 //相减( x-v.x,y-v.y )
    void clamp(const Vec2& min,const Vec2& max); //将向量值限制在[min,max]区间内
    void negate();                                //向量取负( -x,-y )
    void normalize();                             //标准化向量. 若为零向量,忽略
    void scale(float scalar);                     //x,y坐标同时放缩
    void scale(const Vec2& scale);                //x,y坐标分别放缩
    void rotate(const Vec2& point,float angle);  //绕point点,旋转angle弧度
 
    float dot(const Vec2& v) const;               //点积: x*v.x + y*v.y
    float cross(const Vec2& v) const;             //叉积: x*v.y - y*v.x
    Vec2  project(const Vec2& v) const;           //投影: 向量在v上的投影向量
 
    float distance(const Vec2& v) const;          //与v的距离.
    float distanceSquared(const Vec2& v) const;   //与v的距离平方.
    float length() const;                         //向量长度.     即与原点的距离
    float lengthSquared() const;                  //向量长度平方. 即与原点的距离平方
     
    Vec2 getNormalized() const;                   //获取向量的标准化形式. 若为零向量,返回(0,0)
 
    inline Vec2 getPerp() const;                  //逆时针旋转90度. Vec2(-y,x);
    inline Vec2 getRPerp() const                  //顺时针旋转90度. Vec2(y,-x);
     
    inline float getAngle() const;                //与X轴的夹角(弧度)
    float        getAngle(const Vec2& v) const;   //与v向量的夹角(弧度)
     
    inline Vec2 getMidpoint(const Vec2& v) const; //计算两点间的中点
     
 
    //将向量值限制在[min,max]区间内,返回该点
    inline Vec2 getClampPoint(const Vec2& min,const Vec2& max) const
    {
        return Vec2(clampf(x,min.x,max.x),clampf(y,min.y,max.y));
    }
     
     
    bool isZero() const; //是否为(0,0)
    bool isOne() const;  //是否为(1,1)
 
 
    //判断target是否在坐标点模糊偏差为var的范围内.
    //if( (x - var <= target.x && target.x <= x + var) && 
    //    (y - var <= target.y && target.y <= y + var) ) 
    //      return true;
    bool fuzzyEquals(const Vec2& target,float variance) const;
 
 
    //以pivot为轴,逆时针旋转angle度(弧度)
    Vec2 rotateByAngle(const Vec2& pivot,float angle) const;
 
 
    //绕other向量旋转
    //返回向量: 角度 this.getAngle() +other.getAngle();
    //          长度 this.getLength()*other.getLength();
    inline Vec2 rotate(const Vec2& other) const {
        return Vec2(x*other.x - y*other.y,x*other.y + y*other.x);
    };
 
 
    //绕other向量旋转前的向量值
    //返回向量: 角度 this.getAngle() -other.getAngle(); 
    //          长度 this.getLength()*other.getLength();
    //(这里是不是有点问题,难道不应该是this.getLength()/other.getLength()么?)
    inline Vec2 unrotate(const Vec2& other) const {
        return Vec2(x*other.x + y*other.y,y*other.x - x*other.y);
    };
 
 
    //两个点a和b之间的线性插值
    //alpha ==0 ? a alpha ==1 ? b 否则为a和b之间的一个值
    inline Vec2 lerp(const Vec2& other,float alpha) const {
        return *this * (1.f - alpha) + other * alpha;
    };
 
     
    //平滑更新向量的当前位置,指向目标向量target.
    //responseTime定义了平滑时间量,该值越大结果越平滑,相应的延迟时间越长。
    //如果希望向量紧跟target向量,提供一个相对elapsedTime小很多的responseTime值即可。
    //参数
    //target        目标值
    //elapsedTime   消逝时间
    //responseTime  响应时间
    void smooth(const Vec2& target,float elapsedTime,float responseTime);
 
 
/**
 * 自定义运算
 *     compOp 
 */
    //对该点向量形式的各分量进行function参数来指定的运算, 
    //如absf,floorf,ceilf,roundf等,
    //任何函数拥有如下形式:float func(float)均可。
    //例如:我们对x,y进行floor运算,则调用方法为p.compOp(floorf);
    //3.0
    inline Vec2 compOp(std::function<float(float)> function) const
    {
        return Vec2(function(x),function(y));
    }
 
 
/**
 * 兼容代码
 *     估计是要被抛弃了~(>_<)~
 */
    void  setPoint(float xx,float yy);           //同set(float xx,float yy)
    bool  equals(const Vec2& target) const;       //同==
    float getLength() const;                      //同length()
    float getLengthSq() const;                    //同lengthSquared()
    float getDistance(const Vec2& other) const;   //同distance(const Vec2& v)
    float getDistanceSq(const Vec2& other) const; //同distanceSquared(const Vec2& v)

4、运算符重载

inline const Vec2 operator+(const Vec2& v) const; //( x+v.x,y+v.y )
    inline const Vec2 operator-(const Vec2& v) const; //( x-v.x,y-v.y )
    inline const Vec2 operator*(float s) const;       //( x*s,y*s )
    inline const Vec2 operator/(float s) const;       //( x/s,y/s )
    inline const Vec2 operator-() const;              //( -x,-y )
 
    inline Vec2& operator+=(const Vec2& v);           //(x,y) = ( x+v.x,y+v.y )
    inline Vec2& operator-=(const Vec2& v);           //(x,y) = ( x-v.x,y-v.y )
    inline Vec2& operator*=(float s);                 //(x,y) = ( x*s,y*s )
 
    inline bool operator<(const Vec2& v) const;
    inline bool operator==(const Vec2& v) const;
    inline bool operator!=(const Vec2& v) const;

5、静态函数与常量

/**
 * 静态方法
 */
    static void add(const Vec2& v1,const Vec2& v2,Vec2* dst);                    //dst = v1 + v2
    static void subtract(const Vec2& v1,Vec2* dst);               //dst = v1 - v2
    static void clamp(const Vec2& v,const Vec2& min,const Vec2& max,Vec2* dst); //将向量v限制在[min,max]区间内,结果存入dst
 
    static float angle(const Vec2& v1,const Vec2& v2);                            //两向量夹角(弧度)
    static float dot(const Vec2& v1,const Vec2& v2);                              //两向量点积
    static inline Vec2 forAngle(const float a);                                    //返回向量坐标 x=cos(a),y=sin(a)
 
 
/**
 * 静态常量
 */
    static const Vec2 ZERO;                 //Vec2(0,0)
    static const Vec2 ONE;                  //Vec2(1,1)
    static const Vec2 UNIT_X;               //Vec2(1,0)
    static const Vec2 UNIT_Y;               //Vec2(0,1)
    static const Vec2 ANCHOR_MIDDLE;        //Vec2(0.5,0.5)
    static const Vec2 ANCHOR_BOTTOM_LEFT;   //Vec2(0,0)
    static const Vec2 ANCHOR_TOP_LEFT;      //Vec2(0,1)
    static const Vec2 ANCHOR_BOTTOM_RIGHT;  //Vec2(1,0)
    static const Vec2 ANCHOR_TOP_RIGHT;     //Vec2(1,1)
    static const Vec2 ANCHOR_MIDDLE_RIGHT;  //Vec2(1,0.5)
    static const Vec2 ANCHOR_MIDDLE_LEFT;   //Vec2(0,0.5)
    static const Vec2 ANCHOR_MIDDLE_TOP;    //Vec2(0.5,1)
    static const Vec2 ANCHOR_MIDDLE_BOTTOM; //Vec2(0.5,0)

6、线段相交检测

这些用于检测线段相交的函数,也都是静态的成员函数

/**
    线段相交检测 v3.0
    参数:
        A   为线段L1起点. L1 = (A - B)
        B   为L1终点    . L1 = (A - B)
        C   为线段L2起点. L2 = (C - D)
        D   为L2终点    . L2 = (C - D)
        S   为L1上计算各点的插值参数,计算方法为:p = A + S*(B - A)
        T   为L2上计算各点的插值参数,计算方法为:p = C + T*(D - C)
 */
 
    //直线AB与线段CD是否平行
    static bool isLineParallel(const Vec2& A,const Vec2& B,const Vec2& C,const Vec2& D);
    //直线AB与线段CD是否重叠
    static bool isLineOverlap(const Vec2& A,const Vec2& D);
    //直线AB与直线CD是否相交    
    static bool isLineIntersect(const Vec2& A,const Vec2& D,float *S = nullptr,float *T = nullptr);
 
    //线段AB与线段CD是否重叠
    static bool isSegmentOverlap(const Vec2& A,Vec2* S = nullptr,Vec2* E = nullptr);
    //线段AB与线段CD是否相交
    static bool isSegmentIntersect(const Vec2& A,const Vec2& D);
 
    //返回直线AB与直线CD的交点
    static Vec2 getIntersectPoint(const Vec2& A,const Vec2& D);

【Size】

Size比较简单,只是一个用来表示尺寸大小的类。宽为width,高为height

和Vec2一样,也对一些运算符进行了重载。

与2.x相比,没有太大的变化。

PS:因为和Vec2一样,都只有两个成员变量,所以Size和Vec2之间可以相互转换。


1、主要函数如下

class CC_DLL Size
{
/**
 * Size只有两个成员变量width,height
 */
    float width;   //宽
    float height;  //高
 
 
/**
 * 构造函数
 */
    Size();                           //(0,0)
    Size(float width,float height);  //(width,height)
    Size(const Size& other);          //other
    explicit Size(const Vec2& point); //(显式)构造函数. 构造时Size size = Size(Vec2&),而不能Size size = vec2;
 
 
/**
 * 相关操作
 *     - setSize
 *     - equals
 *     - Vec2()
 */
    void setSize(float width,float height); //设置尺寸
    bool equals(const Size& target) const;   //判断是否等于target
 
    //Size::Vec2()
    //返回类型为Vec2
    operator Vec2() const { return Vec2(width,height); }  
 
 
/**
 * 静态常量
 */
    static const Size ZERO; //(0,0)
 
 
/**
 * 运算符重载
 */
    Size& operator= (const Size& other);
    Size& operator= (const Vec2& point); //可以用Vec2赋值
    Size operator+(const Size& right) const;
    Size operator-(const Size& right) const;
    Size operator*(float a) const;
    Size operator/(float a) const;
 
};

【Rect】

Rect是一个矩形类。包含两个成员属性:起始坐标(左下角)Vec2、矩阵尺寸大小Size

Rect只对“=”运算符进行了重载。

与2.x相比,多了一个函数unionWithRect,用于合并两个矩形。

值得注意的是Rect类中:

intersectsRect函数,可以用作两个Rect矩形是否相交,即碰撞检测。

containsPoint 函数,可以用作判断点Vec2是否在Rect矩形中。

unionWithRect 函数,可以用做将两矩形进行合并操作。


1、主要函数如下

class CC_DLL Rect
{
public:
    Vec2 origin; //起始坐标: 矩形左下角坐标
    Size  size;  //尺寸大小
 
 
/**
 * 构造函数
 */
    Rect();
    Rect(float x,float y,float width,float height);
    Rect(const Rect& other);
 
 
/**
 * 运算符重载
 *     只重载了 “=” 运算符
 */
    Rect& operator= (const Rect& other);
 
 
/**
 * 相关操作
 *     - setRect
 *     - getMinX,getMidX,getMaxX
 *     - getMinY,getMidY,getMaxY
 *     - equals,containsPoint,intersectsRect
 *     - unionWithRect
 */
    //设置矩形
    void setRect(float x,float height);
 
 
    //获取矩形信息
    float getMinX() const; //origin.x
    float getMidX() const; //origin.x + size.width/2
    float getMaxX() const; //origin.x + size.width
 
    float getMinY() const; //origin.y
    float getMidY() const; //origin.y + size.height/2
    float getMaxY() const; //origin.y + size.height
 
 
    //判断是否与rect相同. 原点相同,尺寸相同.
    bool equals(const Rect& rect) const;
 
    //判断point是否包含在矩形内或四条边上
    bool containsPoint(const Vec2& point) const;
 
    //判断矩形是否相交. 常常用作碰撞检测.
    bool intersectsRect(const Rect& rect) const;
 
 
    //与rect矩形合并. 并返回结果. v3.0
    //不会改变原矩形的值
    Rect unionWithRect(const Rect & rect) const;
 
 
/**
 * 静态常量
 *     Rect::ZERO
 */
    static const Rect ZERO;
 
};

2、精灵创建中的一种方式

还记得Sprite的几种创建方式吗?里面有一种创建方式如下:

>Sprite::create(const std::string& filename,const Rect& rect)

若用Rect来作为创建Sprite精灵的参数,需要注意,从大图中截取某一区域的图片的Rect rect的构造应该是这样的:

>Rect("小图左上角坐标x","小图左上角坐标y",小图宽,小图高);

使用的是UIKit坐标系,而不是cocos2dx的OpenGL坐标系是不一样的。

如下图所示:


3、矩形合并函数unionWithRect

看几张图,你应该就会明白了。

两个黑色矩形区域,使用unionWithRect合并后,变成红色矩形区域。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是