/** * The MIT License (MIT) * * Copyright (c) 2012-2017 DragonBones team and other contributors * * 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. */ using System; using System.Collections.Generic; namespace DragonBones { /// /// - 2D Transform matrix. /// /// DragonBones 3.0 /// en_US /// /// - 2D 转换矩阵。 /// /// DragonBones 3.0 /// zh_CN public class Matrix { /// /// - The value that affects the positioning of pixels along the x axis when scaling or rotating an image. /// /// 1.0 /// DragonBones 3.0 /// en_US /// /// - 缩放或旋转图像时影响像素沿 x 轴定位的值。 /// /// 1.0 /// DragonBones 3.0 /// zh_CN public float a = 1.0f; /// /// - The value that affects the positioning of pixels along the y axis when rotating or skewing an image. /// /// 0.0 /// DragonBones 3.0 /// en_US /// /// - 旋转或倾斜图像时影响像素沿 y 轴定位的值。 /// /// 0.0 /// DragonBones 3.0 /// zh_CN public float b = 0.0f; /// /// - The value that affects the positioning of pixels along the x axis when rotating or skewing an image. /// /// 0.0 /// DragonBones 3.0 /// en_US /// /// - 旋转或倾斜图像时影响像素沿 x 轴定位的值。 /// /// 0.0 /// DragonBones 3.0 /// zh_CN public float c = 0.0f; /// /// - The value that affects the positioning of pixels along the y axis when scaling or rotating an image. /// /// 1.0 /// DragonBones 3.0 /// en_US /// /// - 缩放或旋转图像时影响像素沿 y 轴定位的值。 /// /// 1.0 /// DragonBones 3.0 /// zh_CN public float d = 1.0f; /// /// - The distance by which to translate each point along the x axis. /// /// 0.0 /// DragonBones 3.0 /// en_US /// /// - 沿 x 轴平移每个点的距离。 /// /// 0.0 /// DragonBones 3.0 /// zh_CN public float tx = 0.0f; /// /// - The distance by which to translate each point along the y axis. /// /// 0.0 /// DragonBones 3.0 /// en_US /// /// - 沿 y 轴平移每个点的距离。 /// /// 0.0 /// DragonBones 3.0 /// zh_CN public float ty = 0.0f; /// public Matrix() { } public override string ToString() { return "[object DragonBones.Matrix] a:" + a + " b:" + b + " c:" + c + " d:" + d + " tx:" + tx + " ty:" + ty; } /// public Matrix CopyFrom(Matrix value) { this.a = value.a; this.b = value.b; this.c = value.c; this.d = value.d; this.tx = value.tx; this.ty = value.ty; return this; } /// public Matrix CopyFromArray(List value, int offset = 0) { this.a = value[offset]; this.b = value[offset + 1]; this.c = value[offset + 2]; this.d = value[offset + 3]; this.tx = value[offset + 4]; this.ty = value[offset + 5]; return this; } /// /// - Convert to unit matrix. /// The resulting matrix has the following properties: a=1, b=0, c=0, d=1, tx=0, ty=0. /// /// DragonBones 3.0 /// en_US /// /// - 转换为单位矩阵。 /// 该矩阵具有以下属性:a=1、b=0、c=0、d=1、tx=0、ty=0。 /// /// DragonBones 3.0 /// zh_CN public Matrix Identity() { this.a = this.d = 1.0f; this.b = this.c = 0.0f; this.tx = this.ty = 0.0f; return this; } /// /// - Multiplies the current matrix with another matrix. /// /// - The matrix that needs to be multiplied. /// DragonBones 3.0 /// en_US /// /// - 将当前矩阵与另一个矩阵相乘。 /// /// - 需要相乘的矩阵。 /// DragonBones 3.0 /// zh_CN public Matrix Concat(Matrix value) { var aA = this.a * value.a; var bA = 0.0f; var cA = 0.0f; var dA = this.d * value.d; var txA = this.tx * value.a + value.tx; var tyA = this.ty * value.d + value.ty; if (this.b != 0.0f || this.c != 0.0f) { aA += this.b * value.c; bA += this.b * value.d; cA += this.c * value.a; dA += this.c * value.b; } if (value.b != 0.0f || value.c != 0.0f) { bA += this.a * value.b; cA += this.d * value.c; txA += this.ty * value.c; tyA += this.tx * value.b; } this.a = aA; this.b = bA; this.c = cA; this.d = dA; this.tx = txA; this.ty = tyA; return this; } /// /// - Convert to inverse matrix. /// /// DragonBones 3.0 /// en_US /// /// - 转换为逆矩阵。 /// /// DragonBones 3.0 /// zh_CN public Matrix Invert() { var aA = this.a; var bA = this.b; var cA = this.c; var dA = this.d; var txA = this.tx; var tyA = this.ty; if (bA == 0.0f && cA == 0.0f) { this.b = this.c = 0.0f; if (aA == 0.0f || dA == 0.0f) { this.a = this.b = this.tx = this.ty = 0.0f; } else { aA = this.a = 1.0f / aA; dA = this.d = 1.0f / dA; this.tx = -aA * txA; this.ty = -dA * tyA; } return this; } var determinant = aA * dA - bA * cA; if (determinant == 0.0f) { this.a = this.d = 1.0f; this.b = this.c = 0.0f; this.tx = this.ty = 0.0f; return this; } determinant = 1.0f / determinant; var k = this.a = dA * determinant; bA = this.b = -bA * determinant; cA = this.c = -cA * determinant; dA = this.d = aA * determinant; this.tx = -(k * txA + cA * tyA); this.ty = -(bA * txA + dA * tyA); return this; } /// /// - Apply a matrix transformation to a specific point. /// /// - X coordinate. /// - Y coordinate. /// - The point after the transformation is applied. /// - Whether to ignore tx, ty's conversion to point. /// DragonBones 3.0 /// en_US /// /// - 将矩阵转换应用于特定点。 /// /// - 横坐标。 /// - 纵坐标。 /// - 应用转换之后的点。 /// - 是否忽略 tx,ty 对点的转换。 /// DragonBones 3.0 /// zh_CN public void TransformPoint(float x, float y, Point result, bool delta = false) { result.x = this.a * x + this.c * y; result.y = this.b * x + this.d * y; if (!delta) { result.x += this.tx; result.y += this.ty; } } /// public void TransformRectangle(Rectangle rectangle, bool delta = false) { var a = this.a; var b = this.b; var c = this.c; var d = this.d; var tx = delta ? 0.0f : this.tx; var ty = delta ? 0.0f : this.ty; var x = rectangle.x; var y = rectangle.y; var xMax = x + rectangle.width; var yMax = y + rectangle.height; var x0 = a * x + c * y + tx; var y0 = b * x + d * y + ty; var x1 = a * xMax + c * y + tx; var y1 = b * xMax + d * y + ty; var x2 = a * xMax + c * yMax + tx; var y2 = b * xMax + d * yMax + ty; var x3 = a * x + c * yMax + tx; var y3 = b * x + d * yMax + ty; var tmp = 0.0f; if (x0 > x1) { tmp = x0; x0 = x1; x1 = tmp; } if (x2 > x3) { tmp = x2; x2 = x3; x3 = tmp; } rectangle.x = (float)Math.Floor(x0 < x2 ? x0 : x2); rectangle.width = (float)Math.Ceiling((x1 > x3 ? x1 : x3) - rectangle.x); if (y0 > y1) { tmp = y0; y0 = y1; y1 = tmp; } if (y2 > y3) { tmp = y2; y2 = y3; y3 = tmp; } rectangle.y = (float)Math.Floor(y0 < y2 ? y0 : y2); rectangle.height = (float)Math.Ceiling((y1 > y3 ? y1 : y3) - rectangle.y); } } }