2013-10-12 15:25:45 +08:00
|
|
|
/****************************************************************************
|
2014-01-07 11:47:11 +08:00
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
2018-01-29 16:25:32 +08:00
|
|
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2013-10-12 15:25:45 +08:00
|
|
|
|
2022-07-09 01:23:11 +08:00
|
|
|
https://axis-project.github.io/
|
2013-10-12 15:25:45 +08:00
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
2014-04-30 08:37:36 +08:00
|
|
|
|
|
|
|
#include "math/CCAffineTransform.h"
|
|
|
|
|
2013-10-12 15:25:45 +08:00
|
|
|
#include <algorithm>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_BEGIN
|
2013-10-12 15:25:45 +08:00
|
|
|
|
|
|
|
AffineTransform __CCAffineTransformMake(float a, float b, float c, float d, float tx, float ty)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
AffineTransform t;
|
|
|
|
t.a = a;
|
|
|
|
t.b = b;
|
|
|
|
t.c = c;
|
|
|
|
t.d = d;
|
|
|
|
t.tx = tx;
|
|
|
|
t.ty = ty;
|
|
|
|
return t;
|
2013-10-12 15:25:45 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 __CCPointApplyAffineTransform(const Vec2& point, const AffineTransform& t)
|
2013-10-12 15:25:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
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;
|
2013-10-12 15:25:45 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 PointApplyTransform(const Vec2& point, const Mat4& transform)
|
2013-12-10 09:32:51 +08:00
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec3 vec(point.x, point.y, 0);
|
2014-04-11 17:19:32 +08:00
|
|
|
transform.transformPoint(&vec);
|
2014-05-15 01:07:09 +08:00
|
|
|
return Vec2(vec.x, vec.y);
|
2013-12-10 09:32:51 +08:00
|
|
|
}
|
|
|
|
|
2021-10-23 23:27:14 +08:00
|
|
|
Vec2 __CCSizeApplyAffineTransform(const Vec2& size, const AffineTransform& t)
|
2013-10-12 15:25:45 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Vec2 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;
|
2013-10-12 15:25:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
AffineTransform AffineTransformMakeIdentity()
|
|
|
|
{
|
|
|
|
return __CCAffineTransformMake(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern const AffineTransform AffineTransformIdentity = AffineTransformMakeIdentity();
|
2021-12-25 10:04:45 +08:00
|
|
|
const AffineTransform AffineTransform::IDENTITY = AffineTransformMakeIdentity();
|
2013-10-12 15:25:45 +08:00
|
|
|
|
|
|
|
Rect RectApplyAffineTransform(const Rect& rect, const AffineTransform& anAffineTransform)
|
|
|
|
{
|
|
|
|
float top = rect.getMinY();
|
|
|
|
float left = rect.getMinX();
|
|
|
|
float right = rect.getMaxX();
|
|
|
|
float bottom = rect.getMaxY();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
Vec2 topLeft = PointApplyAffineTransform(Vec2(left, top), anAffineTransform);
|
|
|
|
Vec2 topRight = PointApplyAffineTransform(Vec2(right, top), anAffineTransform);
|
|
|
|
Vec2 bottomLeft = PointApplyAffineTransform(Vec2(left, bottom), anAffineTransform);
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 bottomRight = PointApplyAffineTransform(Vec2(right, bottom), anAffineTransform);
|
2013-10-12 15:25:45 +08:00
|
|
|
|
|
|
|
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));
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2013-10-12 15:25:45 +08:00
|
|
|
return Rect(minX, minY, (maxX - minX), (maxY - minY));
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
Rect RectApplyTransform(const Rect& rect, const Mat4& transform)
|
2013-12-10 09:32:51 +08:00
|
|
|
{
|
|
|
|
float top = rect.getMinY();
|
|
|
|
float left = rect.getMinX();
|
|
|
|
float right = rect.getMaxX();
|
|
|
|
float bottom = rect.getMaxY();
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec3 topLeft(left, top, 0);
|
|
|
|
Vec3 topRight(right, top, 0);
|
|
|
|
Vec3 bottomLeft(left, bottom, 0);
|
|
|
|
Vec3 bottomRight(right, bottom, 0);
|
2014-04-11 17:19:32 +08:00
|
|
|
transform.transformPoint(&topLeft);
|
|
|
|
transform.transformPoint(&topRight);
|
|
|
|
transform.transformPoint(&bottomLeft);
|
|
|
|
transform.transformPoint(&bottomRight);
|
2013-12-10 09:32:51 +08:00
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2013-10-12 15:25:45 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
AffineTransform AffineTransformRotate(const AffineTransform& t, float anAngle)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
float sine = sinf(anAngle);
|
2013-10-12 15:25:45 +08:00
|
|
|
float cosine = cosf(anAngle);
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
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);
|
2013-10-12 15:25:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Concatenate `t2' to `t1' and return the result:
|
|
|
|
t' = t1 * t2 */
|
|
|
|
AffineTransform AffineTransformConcat(const AffineTransform& t1, const AffineTransform& t2)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
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
|
2013-10-12 15:25:45 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
Mat4 TransformConcat(const Mat4& t1, const Mat4& t2)
|
2013-12-11 03:07:15 +08:00
|
|
|
{
|
2014-04-09 14:21:41 +08:00
|
|
|
return t1 * t2;
|
2013-12-11 03:07:15 +08:00
|
|
|
}
|
|
|
|
|
2013-10-12 15:25:45 +08:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
2021-12-25 10:04:45 +08:00
|
|
|
determinant * (t.c * t.ty - t.d * t.tx), determinant * (t.b * t.tx - t.a * t.ty));
|
2013-10-12 15:25:45 +08:00
|
|
|
}
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_END
|