斜切(Skew)、逆矩阵(Invert)、变换点/向量/矩形边界,以及描边缩放因子。
| 函数 | 说明 |
|---|---|
int xgeShapeExMatrixSkew(xge_shape_ex_matrix_t* pMatrix, float fXRadians, float fYRadians) | 追加斜切 |
int xgeShapeExMatrixInvert(xge_shape_ex_matrix_t* pOut, const ...* pMatrix) | 求逆矩阵 |
int xgeShapeExMatrixPoint(xge_vec2_t* pOut, const ...* pMatrix, xge_vec2_t tPoint) | 变换点(含平移) |
int xgeShapeExMatrixVector(xge_vec2_t* pOut, const ...* pMatrix, xge_vec2_t tVector) | 变换向量(忽略平移) |
int xgeShapeExMatrixRectBounds(xge_rect_t* pOut, const ...* pMatrix, xge_rect_t tRect) | 变换矩形的 AABB 包围盒 |
int xgeShapeExMatrixStrokeScale(float* pScale, const ...* pMatrix) | 获取描边缩放因子 |
gcc -O2 -I. -o ch35.exe ch35_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch35.exe
xge_shape_ex_matrix_t mat;
xgeShapeExMatrixIdentity(&mat);
// X 方向斜切 30°
xgeShapeExMatrixSkew(&mat, 3.14159265f/6.0f, 0);
// 应用到 ShapeEx
xgeShapeExTransformSet(shape, &mat);// 已知世界变换
xge_shape_ex_matrix_t world;
xgeShapeExMatrixIdentity(&world);
xgeShapeExMatrixTranslate(&world, 200, 100);
xgeShapeExMatrixRotate(&world, 0.5f);
// 求逆
xge_shape_ex_matrix_t inv;
xgeShapeExMatrixInvert(&inv, &world);
// 将屏幕点转换到局部坐标
xge_vec2_t screen = { 350, 250 };
xge_vec2_t local;
xgeShapeExMatrixPoint(&local, &inv, screen);xge_rect_t src = { 0, 0, 100, 50 };
xge_shape_ex_matrix_t mat;
xgeShapeExMatrixIdentity(&mat);
xgeShapeExMatrixRotate(&mat, 3.14159265f/4.0f);
// 获取旋转后的轴对齐包围盒
xge_rect_t bounds;
xgeShapeExMatrixRectBounds(&bounds, &mat, src);
// bounds 比 src 大(旋转后外接矩形变大)将以下代码保存为 ch35_main.c,编译后运行即可看到斜切、逆变换与边界计算效果:
#include "xge.h"
static xge_shape_ex g_rect = NULL;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x081114FF);
// 斜切效果
xge_shape_ex_matrix_t skew;
xgeShapeExMatrixIdentity(&skew);
xgeShapeExMatrixTranslate(&skew, 80, 80);
xgeShapeExMatrixSkew(&skew, 3.14159265f/6.0f, 0);
xgeShapeExTransformSet(g_rect, &skew);
xgeShapeExFillColor(g_rect, 0x4FD8C2FF);
xgeShapeExDraw(g_rect, 0.25f);
// 旋转 45° + 显示 AABB 包围盒
xge_shape_ex_matrix_t rot;
xgeShapeExMatrixIdentity(&rot);
xgeShapeExMatrixTranslate(&rot, 450, 200);
xgeShapeExMatrixRotate(&rot, 3.14159265f/4.0f);
xgeShapeExTransformSet(g_rect, &rot);
xgeShapeExFillColor(g_rect, 0xFFB454FF);
xgeShapeExDraw(g_rect, 0.25f);
// 计算并绘制 AABB 包围盒
xge_rect_t src = { 0, 0, 150, 100 };
xge_rect_t bounds;
xgeShapeExMatrixRectBounds(&bounds, &rot, src);
bounds.fX += 450; bounds.fY += 200;
xgeShapeRectStroke(bounds, 1.0f, 0xFF6B5E80);
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 800;
d.iHeight = 600;
d.sTitle = "ch35 - Matrix Advanced";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
xgeShapeExCreate(&g_rect);
xgeShapeExMoveTo(g_rect, 0, 0);
xgeShapeExLineTo(g_rect, 150, 0);
xgeShapeExLineTo(g_rect, 150, 100);
xgeShapeExLineTo(g_rect, 0, 100);
xgeShapeExClose(g_rect);
xgeRun(onFrame, NULL);
xgeShapeExDestroy(g_rect);
xgeUnit();
return 0;
}