## 变换矩阵

``````B'.x = |AB| * cos(α+β) = |AB| * (cosα*cosβ - sinα*sinβ) = B.x * cosβ - B.y * sinβ
B'.y = |AB| * sin(α+β) = |AB| * (cosα*sinβ + sinα*cosβ) = B.x * sinβ + B.y * cosβ

``````#define DEGRESS_TO_RADIANS(\$degress)  ((\$degress) / (180.0 / M_PI))

#define MATRIX_SIZE 4
typedef float Matrix4[MATRIX_SIZE][MATRIX_SIZE];

void rightHandTransformMatrix(Matrix4 matrix, RotateAxis axis, float angle) {
switch (axis) {
case X:
matrix[1][1] = cos(DEGRESS_TO_RADIANS(angle));
matrix[1][2] = -sin(DEGRESS_TO_RADIANS(angle));
matrix[2][1] = sin(DEGRESS_TO_RADIANS(angle));
matrix[2][2] = cos(DEGRESS_TO_RADIANS(angle));
break;
case Y:
matrix[0][0] = cos(DEGRESS_TO_RADIANS(angle));
matrix[0][2] = sin(DEGRESS_TO_RADIANS(angle));
matrix[2][0] = -sin(DEGRESS_TO_RADIANS(angle));
matrix[2][2] = cos(DEGRESS_TO_RADIANS(angle));
break;
case Z:
matrix[0][0] = cos(DEGRESS_TO_RADIANS(angle));
matrix[0][1] = -sin(DEGRESS_TO_RADIANS(angle));
matrix[1][0] = sin(DEGRESS_TO_RADIANS(angle));
matrix[1][1] = cos(DEGRESS_TO_RADIANS(angle));
break;
}
}

## 深度

`ABC`平面沿着`x`轴旋转后，直接的观感就是整个平面的高度坍缩。假如把坐标轴的刻度当做屏幕渲染点(`dp`)，就可以当做旋转发生后，单个`dp`容纳了比原图更多的像素，最终`dp`渲染的颜色由深度(`z`轴数值)更大的像素表示

## 变换实现

``````typedef struct Position {
float x;
float y;
float z;
} Position;

extern Position MakePosition(float x, float y, float z);

@interface SDLTransform : NSObject

/// 坐标轴的旋转角度
@property (nonatomic, assign) CGFloat pitch;
@property (nonatomic, assign) CGFloat yaw;
@property (nonatomic, assign) CGFloat roll;

/// 平移
@property (nonatomic, assign) Position translation;

@end

### 变换顺序

``````@implementation SDLTransform

- (Position)transformCoordinate:(Position)coordinate origin:(Position)origin {
coordinate = MinusPosition(coordinate, origin);
if (self.pitch != NONE_PITCH) {
Matrix4 mat4;
rotateMatrix(mat4, X, self.pitch);
[self transformPosition:coordinate mat:mat4];
}
if (self.yaw != NONE_YAW) {
// Y轴旋转
}
// Z轴旋转 & 平移
return AddPosition(coordinate, origin);
}

@end

### 点渲染

``````@implementation SDLRenderPoint

- (void)appendPixel:(RGBAColor)color depth:(float)depth {
NSInteger depthIndex = [self insertIndexOf:depth];
if (color.alpha == NONE_ALPHA) {
[self removeAllPixelsAfterDepth:depth];
}
[self insertPixel:(RGBAColor)color atIndex:depthIndex];
}

@end

``````@implementation SDLRenderPoint

- (RGBAColor)renderColor {
if ([self isEmpty]) {
return clearColor();
}
return [self mixedPixelsWithOptions:SDLMixedReverse:usingBlock:^RGBAColor(RGBAColor current, RGBAColor previous) {
return [self mixedForegroundColor:current backgroundColor:previous];
}];
}

@end