专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 图形/图像

【计算机图形学】3-2 二维几何变换根本代码

发布时间:2011-06-27 20:29:42 文章来源:www.iduyao.cn 采编人员:星星草
【计算机图形学】3-2 二维几何变换基本代码

返回目录


基本理论参见:【计算机图形学】3-1 二维几何变换基本理论

注:这里不考虑插值的问题。


全部的代码都在https://github.com/CyberZHG/ZPIC 上,欢迎各位前来围观和提出意见。


效果截图:

移动:


缩放:


旋转:


错切 :


改变旋转中心后的旋转:



transform_matrix.h

#ifndef TRANSFORM_MATRIX_H_INCLUDED
#define TRANSFORM_MATRIX_H_INCLUDED

#include <math.h>
#include "define.h"

typedef struct Transform_Matrix_9d
{
    double m[3][3];
}Transform_Matrix_9d;

void transform_matrix_init(Transform_Matrix_9d *matrix);
void transform_matrix_clear(Transform_Matrix_9d *matrix);
void transform_matrix_add(Transform_Matrix_9d *m1, const Transform_Matrix_9d m2);
void transform_matrix_substract(Transform_Matrix_9d *m1, const Transform_Matrix_9d m2);
void transform_matrix_multiply(Transform_Matrix_9d *m1, const Transform_Matrix_9d m2);
void transform_matrix_copy(Transform_Matrix_9d *m1, const Transform_Matrix_9d m2);
void transform_matrix_transformPoint(const Transform_Matrix_9d matrix, int32 *x, int32 *y);
void transform_matrix_move(Transform_Matrix_9d *matrix, double tx, double ty);
void transform_matrix_scale(Transform_Matrix_9d *matrix, double sx, double sy);
void transform_matrix_rotate(Transform_Matrix_9d *matrix, double angle);
void transform_matrix_shear(Transform_Matrix_9d *matrix, double b, double d);

#endif // TRANSFORM_MATRIX_H_INCLUDED

transform_matrix.c

#include "transform_matrix.h"

void transform_matrix_init(Transform_Matrix_9d *matrix)
{
    int32 i, j;
    for(i=0;i<3;++i)
    {
        for(j=0;j<3;++j)
        {
            matrix->m[i][j] = 0.0;
        }
        matrix->m[i][i] = 1.0;
    }
}

void transform_matrix_clear(Transform_Matrix_9d *matrix)
{
    int32 i, j;
    for(i=0;i<3;++i)
    {
        for(j=0;j<3;++j)
        {
            matrix->m[i][j] = 0.0;
        }
    }
}

void transform_matrix_add(Transform_Matrix_9d *m1, const Transform_Matrix_9d m2)
{
    int32 i, j;
    for(i=0;i<3;++i)
    {
        for(j=0;j<3;++j)
        {
            m1->m[i][j] += m2.m[i][j];
        }
    }
}

void transform_matrix_substract(Transform_Matrix_9d *m1, const Transform_Matrix_9d m2)
{
    int32 i, j;
    for(i=0;i<3;++i)
    {
        for(j=0;j<3;++j)
        {
            m1->m[i][j] -= m2.m[i][j];
        }
    }
}

void transform_matrix_multiply(Transform_Matrix_9d *m1, const Transform_Matrix_9d m2)
{
    int32 i, j, k;
    Transform_Matrix_9d temp;
    transform_matrix_clear(&temp);
    for(i=0;i<3;++i)
    {
        for(j=0;j<3;++j)
        {
            for(k=0;k<3;++k)
            {
                temp.m[i][j] += m1->m[i][k] * m2.m[k][j];
            }
        }
    }
    for(i=0;i<3;++i)
    {
        for(j=0;j<3;++j)
        {
            m1->m[i][j] = temp.m[i][j];
        }
    }
}

void transform_matrix_copy(Transform_Matrix_9d *m1, const Transform_Matrix_9d m2)
{
    int32 i, j;
    for(i=0;i<3;++i)
    {
        for(j=0;j<3;++j)
        {
            m1->m[i][j] = m2.m[i][j];
        }
    }
}

void transform_matrix_transformPoint(const Transform_Matrix_9d matrix, int32 *x, int32 *y)
{
    int32 tx, ty;
    tx = (int)(*x * matrix.m[0][0] + *y * matrix.m[1][0] + matrix.m[2][0]);
    ty = (int)(*x * matrix.m[0][1] + *y * matrix.m[1][1] + matrix.m[2][1]);
    *x = tx;
    *y = ty;
}

void transform_matrix_move(Transform_Matrix_9d *matrix, double tx, double ty)
{
    Transform_Matrix_9d moveMatrix;
    transform_matrix_init(&moveMatrix);
    moveMatrix.m[2][0] = tx;
    moveMatrix.m[2][1] = ty;
    transform_matrix_multiply(matrix, moveMatrix);
}

void transform_matrix_scale(Transform_Matrix_9d *matrix, double sx, double sy)
{
    Transform_Matrix_9d scaleMatrix;
    transform_matrix_init(&scaleMatrix);
    scaleMatrix.m[0][0] = sx;
    scaleMatrix.m[1][1] = sy;
    transform_matrix_multiply(matrix, scaleMatrix);
}

void transform_matrix_rotate(Transform_Matrix_9d *matrix, double angle)
{
    Transform_Matrix_9d rotateMatrix;
    transform_matrix_init(&rotateMatrix);
    rotateMatrix.m[0][0] = rotateMatrix.m[1][1] = cos(angle);
    rotateMatrix.m[1][0] = - (rotateMatrix.m[0][1] = sin(angle));
    transform_matrix_multiply(matrix, rotateMatrix);
}

void transform_matrix_shear(Transform_Matrix_9d *matrix, double b, double d)
{
    Transform_Matrix_9d shearMatrix;
    transform_matrix_init(&shearMatrix);
    shearMatrix.m[0][1] = b;
    shearMatrix.m[1][0] = d;
    transform_matrix_multiply(matrix, shearMatrix);
}

transform_selection.h

#ifndef TRANSFORM_SELECTION_H_INCLUDED
#define TRANSFORM_SELECTION_H_INCLUDED

#include <stdlib.h>
#include <math.h>
#include "define.h"
#include "gui.h"
#include "draw.h"
#include "transform_matrix.h"

typedef struct Transform_Selection_10i2f1m
{
    int32 x[4], y[4];
    float cx, cy;
    draw_color **color;
    int32 **px;
    int32 **py;
    Transform_Matrix_9d transMatrix;
}Transform_Selection_10i2f1m;

void transform_selection_display(void);
void transform_selection_mouseEvent(int32 state, int32 x, int32 y);
void transform_selection_keyboardEvent(int32 key, int32 state);

#endif // TRANSFORM_SELECTION_H_INCLUDED

transform_selection.c

#include "transform_selection.h"

static Transform_Selection_10i2f1m transform_default_selection;
int32 isMovingCenter;
int32 isSelecting;
int32 isSelected;
int32 isMoving;
int32 isResizing;
int32 isRotating;
int32 isShearing;
int32 isMouseDown;
int32 isFinshed;
int32 startX, startY;
int32 endX, endY;
int32 lastEdgeX, lastEdgeY;
Transform_Matrix_9d startMatrix;
int32 isShiftDown;

void transform_selection_display(void)
{
    int32 i, j, w, h;
    int32 x[4], y[4], mx, my;
    float cx, cy;
    int32 edgeL, edgeR, edgeB, edgeT;
    draw_color **color;
    int32 **px, **py;
    int32 tx, ty;
    Transform_Matrix_9d *matrix = &transform_default_selection.transMatrix;
    draw_color penColor = draw_pen_getColor();
    draw_color brushColor = draw_brush_getColor();
    draw_pen_setColor(DRAW_COLOR_WHITE);
    draw_brush_setColor(DRAW_COLOR_BLACK);
    for(i=0;i<4;++i)
    {
        x[i] = transform_default_selection.x[i];
        y[i] = transform_default_selection.y[i];
        transform_matrix_transformPoint(*matrix, &x[i], &y[i]);
    }
    edgeL = min(min(x[0], x[1]), min(x[2], x[3]));
    edgeR = max(max(x[0], x[1]), max(x[2], x[3]));
    edgeB = min(min(y[0], y[1]), min(y[2], y[3]));
    edgeT = max(max(y[0], y[1]), max(y[2], y[3]));
    mx = (edgeL + edgeR) >> 1;
    my = (edgeB + edgeT) >> 1;
    cx = transform_default_selection.cx;
    cy = transform_default_selection.cy;
    w = abs(transform_default_selection.x[0] - transform_default_selection.x[2]) - 1;
    h = abs(transform_default_selection.y[0] - transform_default_selection.y[2]) - 1;
    color = transform_default_selection.color;
    px = transform_default_selection.px;
    py = transform_default_selection.py;
    if(isSelecting)
    {
        if(isSelected)
        {
            for(i=0;i<h;++i)
            {
                for(j=0;j<w;++j)
                {
                    gui_setPixel_2i1u(px[i][j], py[i][j], DRAW_COLOR_BLACK);
                }
            }
            for(i=0;i<h;++i)
            {
                for(j=0;j<w;++j)
                {
                    tx = px[i][j], ty = py[i][j];
                    transform_matrix_transformPoint(*matrix, &tx, &ty);
                    gui_setPixel_2i1u(tx, ty, color[i][j]);
                }
            }
            if(isFinshed)
            {
                gui_saveCurrentImage();
                isSelecting = 0;
                isSelected = 0;
                isMoving = 0;
                isResizing = 0;
                isRotating = 0;
                isShearing = 0;
                isFinshed = 0;
                isMouseDown = 0;
                w = abs(transform_default_selection.x[0] - transform_default_selection.x[2]) - 1;
                h = abs(transform_default_selection.y[0] - transform_default_selection.y[2]) - 1;
                for(i=0;i<h;++i)
                {
                    free(transform_default_selection.color[i]);
                    free(transform_default_selection.px[i]);
                    free(transform_default_selection.py[i]);
                }
                free(transform_default_selection.color);
                free(transform_default_selection.px);
                free(transform_default_selection.py);
            }
            else
            {
                draw_line_4i(edgeL, edgeT, edgeR, edgeT);
                draw_line_4i(edgeL, edgeB, edgeR, edgeB);
                draw_line_4i(edgeL, edgeT, edgeL, edgeB);
                draw_line_4i(edgeR, edgeT, edgeR, edgeB);
                draw_dotted_line_4i(x[0], y[0], x[1], y[1]);
                draw_dotted_line_4i(x[1], y[1], x[2], y[2]);
                draw_dotted_line_4i(x[2], y[2], x[3], y[3]);
                draw_dotted_line_4i(x[3], y[3], x[0], y[0]);
                draw_rectangle_4i(edgeL - 3, edgeT - 3, edgeL + 3, edgeT + 3);
                draw_rectangle_4i(edgeL - 3, edgeB - 3, edgeL + 3, edgeB + 3);
                draw_rectangle_4i(edgeR - 3, edgeT - 3, edgeR + 3, edgeT + 3);
                draw_rectangle_4i(edgeR - 3, edgeB - 3, edgeR + 3, edgeB + 3);
                draw_rectangle_4i(edgeL - 3, my - 3, edgeL + 3, my + 3);
                draw_rectangle_4i(mx - 3, edgeB - 3, mx + 3, edgeB + 3);
                draw_rectangle_4i(edgeR - 3, my - 3, edgeR + 3, my + 3);
                draw_rectangle_4i(mx - 3, edgeT - 3, mx + 3, edgeT + 3);
                draw_circle_3i(cx, cy, 3);
                if(isMoving)
                {
                    gui_setMainWindowCursor(CURSOR_SIZEALL);
                }
                else if(isResizing)
                {
                    switch(isResizing)
                    {
                    case POSITION_LEFT:
                        gui_setMainWindowCursor(CURSOR_SIZEWE);
                        break;
                    case POSITION_RIGHT:
                        gui_setMainWindowCursor(CURSOR_SIZEWE);
                        break;
                    case POSITION_TOP:
                        gui_setMainWindowCursor(CURSOR_SIZENS);
                        break;
                    case POSITION_BOTTOM:
                        gui_setMainWindowCursor(CURSOR_SIZENS);
                        break;
                    case POSITION_TOPLEFT:
                        gui_setMainWindowCursor(CURSOR_SIZENESW);
                        break;
                    case POSITION_TOPRIGHT:
                        gui_setMainWindowCursor(CURSOR_SIZENWSE);
                        break;
                    case POSITION_BOTTOMLEFT:
                        gui_setMainWindowCursor(CURSOR_SIZENWSE);
                        break;
                    case POSITION_BOTTOMRIGHT:
                        gui_setMainWindowCursor(CURSOR_SIZENESW);
                        break;
                    }
                }
                else if(isRotating)
                {
                    gui_setMainWindowCursor(CURSOR_NO);
                }
                else if(isShearing)
                {
                    switch(isShearing)
                    {
                    case POSITION_BOTTOM:
                    case POSITION_TOP:
                        gui_setMainWindowCursor(CURSOR_SIZEWE);
                        break;
                    case POSITION_LEFT:
                    case POSITION_RIGHT:
                        gui_setMainWindowCursor(CURSOR_SIZENS);
                        break;
                    }
                }
            }
        }
        else
        {
            gui_setMainWindowCursor(CURSOR_CROSS);
            draw_dotted_line_4i(x[0], y[0], x[2], y[0]);
            draw_dotted_line_4i(x[0], y[2], x[2], y[2]);
            draw_dotted_line_4i(x[0], y[0], x[0], y[2]);
            draw_dotted_line_4i(x[2], y[0], x[2], y[2]);
        }
    }
    else
    {
        gui_setMainWindowCursor(CURSOR_CROSS);
    }
    draw_pen_setColor(penColor);
    draw_brush_setColor(brushColor);
}

void transform_selection_mouseEvent(int32 state, int32 x, int32 y)
{
    int32 i, j, w, h;
    int32 rx[4], ry[4], mx, my, cx, cy;
    int32 edgeL, edgeR, edgeB, edgeT;
    double angle;
    Transform_Matrix_9d *matrix = &transform_default_selection.transMatrix;
    for(i=0;i<4;++i)
    {
        rx[i] = transform_default_selection.x[i];
        ry[i] = transform_default_selection.y[i];
        transform_matrix_transformPoint(*matrix, &rx[i], &ry[i]);
    }
    edgeL = min(min(rx[0], rx[1]), min(rx[2], rx[3]));
    edgeR = max(max(rx[0], rx[1]), max(rx[2], rx[3]));
    edgeB = min(min(ry[0], ry[1]), min(ry[2], ry[3]));
    edgeT = max(max(ry[0], ry[1]), max(ry[2], ry[3]));
    mx = (edgeL + edgeR) >> 1;
    my = (edgeB + edgeT) >> 1;
    cx = transform_default_selection.cx;
    cy = transform_default_selection.cy;
    switch(state)
    {
    case MOUSE_DOWN_LEFT:
        isMouseDown = 1;
        if(isSelected)
        {
            startX = x;
            startY = y;
            endX = x;
            endY = y;
            transform_matrix_copy(&startMatrix, *matrix);
            if(isResizing)
            {
                switch(isResizing)
                {
                case POSITION_LEFT:
                    lastEdgeX = edgeR;
                    break;
                case POSITION_RIGHT:
                    lastEdgeX = edgeL;
                    break;
                case POSITION_BOTTOM:
                    lastEdgeY = edgeT;
                    break;
                case POSITION_TOP:
                    lastEdgeY = edgeB;
                    break;
                case POSITION_BOTTOMLEFT:
                    lastEdgeX = edgeR;
                    lastEdgeY = edgeT;
                    break;
                case POSITION_BOTTOMRIGHT:
                    lastEdgeX = edgeL;
                    lastEdgeY = edgeT;
                    break;
                case POSITION_TOPLEFT:
                    lastEdgeX = edgeR;
                    lastEdgeY = edgeB;
                    break;
                case POSITION_TOPRIGHT:
                    lastEdgeX = edgeL;
                    lastEdgeY = edgeB;
                    break;
                }
            }
            else if(isShearing)
            {
                switch(isShearing)
                {
                case POSITION_BOTTOM:
                case POSITION_RIGHT:
                    lastEdgeX = edgeL;
                    lastEdgeY = edgeT;
                    break;
                case POSITION_TOP:
                case POSITION_LEFT:
                    lastEdgeX = edgeR;
                    lastEdgeY = edgeB;
                    break;
                }
            }
        }
        else
        {
            isSelecting = 1;
            transform_default_selection.x[0] = x;
            transform_default_selection.y[0] = y;
            transform_default_selection.x[2] = x;
            transform_default_selection.y[2] = y;
            transform_matrix_init(&transform_default_selection.transMatrix);
        }
        break;
    case MOUSE_UP_LEFT:
        isMouseDown = 0;
        if(isSelecting)
        {
            if(isSelected)
            {
                if(isMovingCenter || isMoving || isResizing || isRotating || isShearing)
                {
                    return;
                }
                if(x < edgeL - 10 || x > edgeR + 10 || y < edgeB - 10 || y > edgeT + 10)
                {
                    isFinshed = 1;
                }
            }
            else
            {
                transform_default_selection.x[1] = x;
                transform_default_selection.y[1] = ry[0];
                transform_default_selection.x[3] = rx[0];
                transform_default_selection.y[3] = y;
                transform_default_selection.x[2] = x;
                transform_default_selection.y[2] = y;
                transform_default_selection.cx = (transform_default_selection.x[0] +
                                                  transform_default_selection.x[2]) >> 1;
                transform_default_selection.cy = (transform_default_selection.y[0] +
                                                  transform_default_selection.y[2]) >> 1;
                isSelected = 1;
                w = abs(transform_default_selection.x[0] - transform_default_selection.x[2]) - 1;
                h = abs(transform_default_selection.y[0] - transform_default_selection.y[2]) - 1;
                transform_default_selection.color = (draw_color**)malloc(sizeof(draw_color*) * h);
                transform_default_selection.px = (int32**)malloc(sizeof(int32*) * h);
                transform_default_selection.py = (int32**)malloc(sizeof(int32*) * h);
                for(i=0;i<h;++i)
                {
                    transform_default_selection.color[i] = (draw_color*)malloc(sizeof(draw_color) * w);
                    transform_default_selection.px[i] = (int32*)malloc(sizeof(int32) * w);
                    transform_default_selection.py[i] = (int32*)malloc(sizeof(int32) * w);
                    for(j=0;j<w;++j)
                    {
                        transform_default_selection.color[i][j] = gui_getPixel(min(transform_default_selection.x[0], transform_default_selection.x[2]) + j + 1,
                                                                               min(transform_default_selection.y[0], transform_default_selection.y[2]) + i + 1);
                        transform_default_selection.px[i][j] = min(transform_default_selection.x[0], transform_default_selection.x[2]) + j + 1;
                        transform_default_selection.py[i][j] = min(transform_default_selection.y[0], transform_default_selection.y[2]) + i + 1;
                    }
                }
            }
        }
        break;
    case MOUSE_MOVE:
        if(isSelecting)
        {
            if(isSelected)
            {
                if(isMouseDown)
                {
                    if(isMovingCenter)
                    {
                        transform_default_selection.cx += x - endX;
                        transform_default_selection.cy += y - endY;
                        endX = x;
                        endY = y;
                    }
                    else if(isMoving)
                    {
                        transform_matrix_move(matrix, x - startX, y - startY);
                        transform_default_selection.cx += x - startX;
                        transform_default_selection.cy += y - startY;
                        startX = x;
                        startY = y;
                    }
                    else if(isResizing)
                    {
                        transform_matrix_copy(matrix, startMatrix);
                        switch(isResizing)
                        {
                        case POSITION_LEFT:
                            if(startX != lastEdgeX && endX != lastEdgeX)
                            {
                                transform_matrix_move(matrix, - lastEdgeX, 0);
                                if(x > lastEdgeX)
                                {
                                    transform_matrix_scale(matrix, - 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                transform_matrix_move(matrix, lastEdgeX, 0);
                            }
                            transform_default_selection.cx += (x - endX) * 0.5;
                            endX = x;
                            break;
                        case POSITION_RIGHT:
                            if(startX != lastEdgeX && endX != lastEdgeX)
                            {
                                transform_matrix_move(matrix, - lastEdgeX, 0);
                                if(x < lastEdgeX)
                                {
                                    transform_matrix_scale(matrix, - 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                transform_matrix_move(matrix, lastEdgeX, 0);
                            }
                            transform_default_selection.cx += (x - endX) * 0.5;
                            endX = x;
                            break;
                        case POSITION_BOTTOM:
                            if(startY != lastEdgeY && endY != lastEdgeY)
                            {
                                transform_matrix_move(matrix, 0, - lastEdgeY);
                                if(y > lastEdgeY)
                                {
                                    transform_matrix_scale(matrix, 1.0, - 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0, 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                transform_matrix_move(matrix, 0, lastEdgeY);
                            }
                            transform_default_selection.cy += (y - endY) * 0.5;
                            endY = y;
                            break;
                        case POSITION_TOP:
                            if(startY != lastEdgeY && endY != lastEdgeY)
                            {
                                transform_matrix_move(matrix, 0, - lastEdgeY);
                                if(y < lastEdgeY)
                                {
                                    transform_matrix_scale(matrix, 1.0, - 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0, 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                transform_matrix_move(matrix, 0, lastEdgeY);
                            }
                            transform_default_selection.cy += (y - endY) * 0.5;
                            endY = y;
                            break;
                        case POSITION_BOTTOMLEFT:
                            if(startX != lastEdgeX && endX != lastEdgeX)
                            {
                                transform_matrix_move(matrix, - lastEdgeX, -lastEdgeY);
                                if(x > lastEdgeX)
                                {
                                    transform_matrix_scale(matrix, - 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                if(y > lastEdgeY)
                                {
                                    transform_matrix_scale(matrix, 1.0, - 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0, 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                transform_matrix_move(matrix, lastEdgeX, lastEdgeY);
                            }
                            transform_default_selection.cx += (x - endX) * 0.5;
                            transform_default_selection.cy += (y - endY) * 0.5;
                            endX = x;
                            endY = y;
                            break;
                        case POSITION_BOTTOMRIGHT:
                            if(startX != lastEdgeX && endX != lastEdgeX)
                            {
                                transform_matrix_move(matrix, - lastEdgeX, -lastEdgeY);
                                if(x < lastEdgeX)
                                {
                                    transform_matrix_scale(matrix, - 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                if(y > lastEdgeY)
                                {
                                    transform_matrix_scale(matrix, 1.0, - 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0, 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                transform_matrix_move(matrix, lastEdgeX, lastEdgeY);
                            }
                            transform_default_selection.cx += (x - endX) * 0.5;
                            transform_default_selection.cy += (y - endY) * 0.5;
                            endX = x;
                            endY = y;
                            break;
                        case POSITION_TOPLEFT:
                            if(startX != lastEdgeX && endX != lastEdgeX)
                            {
                                transform_matrix_move(matrix, - lastEdgeX, -lastEdgeY);
                                if(x > lastEdgeX)
                                {
                                    transform_matrix_scale(matrix, - 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                if(y < lastEdgeY)
                                {
                                    transform_matrix_scale(matrix, 1.0, - 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0, 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                transform_matrix_move(matrix, lastEdgeX, lastEdgeY);
                            }
                            transform_default_selection.cx += (x - endX) * 0.5;
                            transform_default_selection.cy += (y - endY) * 0.5;
                            endX = x;
                            endY = y;
                            break;
                        case POSITION_TOPRIGHT:
                            if(startX != lastEdgeX && endX != lastEdgeX)
                            {
                                transform_matrix_move(matrix, - lastEdgeX, -lastEdgeY);
                                if(x < lastEdgeX)
                                {
                                    transform_matrix_scale(matrix, - 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX), 1.0);
                                }
                                if(y < lastEdgeY)
                                {
                                    transform_matrix_scale(matrix, 1.0, - 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                else
                                {
                                    transform_matrix_scale(matrix, 1.0, 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY));
                                }
                                transform_matrix_move(matrix, lastEdgeX, lastEdgeY);
                            }
                            transform_default_selection.cx += (x - endX) * 0.5;
                            transform_default_selection.cy += (y - endY) * 0.5;
                            endX = x;
                            endY = y;
                            break;
                        }
                    }
                    else if(isRotating)
                    {
                        transform_matrix_copy(matrix, startMatrix);
                        angle = atan2(y - cx, x - cy) - atan2(startY - cy, startX - cx);
                        transform_matrix_move(matrix, -cx, -cy);
                        transform_matrix_rotate(matrix, angle);
                        transform_matrix_move(matrix, cx, cy);
                    }
                    else if(isShearing)
                    {
                        switch(isShearing)
                        {
                        case POSITION_BOTTOM:
                            transform_matrix_copy(matrix, startMatrix);
                            transform_matrix_move(matrix, -lastEdgeX, -lastEdgeY);
                            if(x > lastEdgeX)
                            {
                                transform_matrix_shear(matrix, 0.0, - 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX) + 1.0);
                            }
                            else
                            {
                                transform_matrix_shear(matrix, 0.0, 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX) + 1.0);
                            }
                            transform_matrix_move(matrix, lastEdgeX, lastEdgeY);
                            transform_default_selection.cx += x - endX;
                            endX = x;
                            break;
                        case POSITION_RIGHT:
                            transform_matrix_copy(matrix, startMatrix);
                            transform_matrix_move(matrix, -lastEdgeX, -lastEdgeY);
                            if(y < lastEdgeY)
                            {
                                transform_matrix_shear(matrix, - 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY) + 1.0, 0.0);
                            }
                            else
                            {
                                transform_matrix_shear(matrix, 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY) + 1.0, 0.0);
                            }
                            transform_matrix_move(matrix, lastEdgeX, lastEdgeY);
                            transform_default_selection.cy += y - endY;
                            endY = y;
                            break;
                        case POSITION_TOP:
                            transform_matrix_copy(matrix, startMatrix);
                            transform_matrix_move(matrix, -lastEdgeX, -lastEdgeY);
                            if(x < lastEdgeX)
                            {
                                transform_matrix_shear(matrix, 0.0, - 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX) + 1.0);
                            }
                            else
                            {
                                transform_matrix_shear(matrix, 0.0, 1.0 * abs(x - lastEdgeX) / abs(startX - lastEdgeX) + 1.0);
                            }
                            transform_matrix_move(matrix, lastEdgeX, lastEdgeY);
                            transform_default_selection.cx += x - endX;
                            endX = x;
                            break;
                        case POSITION_LEFT:
                            transform_matrix_copy(matrix, startMatrix);
                            transform_matrix_move(matrix, -lastEdgeX, -lastEdgeY);
                            if(y > lastEdgeY)
                            {
                                transform_matrix_shear(matrix, - 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY) + 1.0, 0.0);
                            }
                            else
                            {
                                transform_matrix_shear(matrix, 1.0 * abs(y - lastEdgeY) / abs(startY - lastEdgeY) + 1.0, 0.0);
                            }
                            transform_matrix_move(matrix, lastEdgeX, lastEdgeY);
                            transform_default_selection.cy += y - endY;
                            endY = y;
                            break;
                        }
                    }
                }
                else
                {
                    if(abs(x - cx) <= 4 && abs(y - cy) <= 4)
                    {
                        isMovingCenter = 1;
                        isMoving = 0;
                        isResizing = 0;
                        isRotating = 0;
                        isShearing = 0;
                        return;
                    }
                    if(abs(x - edgeL) <= 4 && abs(y - my) <= 4)
                    {
                        isMovingCenter = 0;
                        isMoving = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isResizing = POSITION_LEFT;
                        return;
                    }
                    if(abs(x - edgeR) <= 4 && abs(y - my) <= 4)
                    {
                        isMovingCenter = 0;
                        isMoving = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isResizing = POSITION_RIGHT;
                        return;
                    }
                    if(abs(x - mx) <= 4 && abs(y - edgeB) <= 4)
                    {
                        isMovingCenter = 0;
                        isMoving = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isResizing = POSITION_BOTTOM;
                        return;
                    }
                    if(abs(x - mx) <= 4 && abs(y - edgeT) <= 4)
                    {
                        isMovingCenter = 0;
                        isMoving = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isResizing = POSITION_TOP;
                        return;
                    }
                    if(abs(x - edgeL) <= 4 && abs(y - edgeT) <= 4)
                    {
                        isMovingCenter = 0;
                        isMoving = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isResizing = POSITION_TOPLEFT;
                        return;
                    }
                    if(abs(x - edgeL) <= 4 && abs(y - edgeB) <= 4)
                    {
                        isMovingCenter = 0;
                        isMoving = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isResizing = POSITION_BOTTOMLEFT;
                        return;
                    }
                    if(abs(x - edgeR) <= 4 && abs(y - edgeT) <= 4)
                    {
                        isMovingCenter = 0;
                        isMoving = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isResizing = POSITION_TOPRIGHT;
                        return;
                    }
                    if(abs(x - edgeR) <= 4 && abs(y - edgeB) <= 4)
                    {
                        isMovingCenter = 0;
                        isMoving = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isResizing = POSITION_BOTTOMRIGHT;
                        return;
                    }
                    if(x > edgeL + 4 && x < edgeR - 4 && y > edgeB + 4 && y < edgeT - 4)
                    {
                        isMovingCenter = 0;
                        isResizing = 0;
                        isRotating = 0;
                        isShearing = 0;
                        isMoving = 1;
                        return;
                    }
                    if((x > edgeR + 4 && x <= edgeR + 8 && y < edgeB - 4 && y >= edgeB - 8))
                    {
                        isMovingCenter = 0;
                        isResizing = 0;
                        isRotating = 1;
                        isShearing = 0;
                        isMoving = 0;
                        return;
                    }
                    if(x >= edgeR - 4 && x < edgeR && y < edgeB - 4 && y >= edgeB - 8)
                    {
                        isMovingCenter = 0;
                        isResizing = 0;
                        isRotating = 0;
                        isShearing = POSITION_BOTTOM;
                        isMoving = 0;
                        return;
                    }
                    if(x > edgeR + 4 && x <= edgeR + 8 && y <= edgeB + 4 && y > edgeB)
                    {
                        isMovingCenter = 0;
                        isResizing = 0;
                        isRotating = 0;
                        isShearing = POSITION_RIGHT;
                        isMoving = 0;
                        return;
                    }
                    if(x > edgeL && x <= edgeL + 4 && y > edgeT + 4 && y <= edgeT + 8)
                    {
                        isMovingCenter = 0;
                        isResizing = 0;
                        isRotating = 0;
                        isShearing = POSITION_TOP;
                        isMoving = 0;
                        return;
                    }
                    if(x > edgeL - 8 && x <= edgeL - 4 && y >= edgeT - 4 && y < edgeT)
                    {
                        isMovingCenter = 0;
                        isResizing = 0;
                        isRotating = 0;
                        isShearing = POSITION_LEFT;
                        isMoving = 0;
                        return;
                    }
                    isMovingCenter = 0;
                    isMoving = 0;
                    isResizing = 0;
                    isRotating = 0;
                    isShearing = 0;
                }
            }
            else
            {
                transform_default_selection.x[2] = x;
                transform_default_selection.y[2] = y;
            }
        }
        break;
    case MOUSE_DOWN_RIGHT:
        if(isSelecting)
        {
            isSelecting = 0;
        }
        break;
    }
}

void transform_selection_keyboardEvent(int32 key, int32 state)
{
    switch(state)
    {
    case KEY_STATE_DOWN:
        switch(key)
        {
        case KEY_VALUE_SHIFT:
            isShiftDown = 1;
        }
        break;
    case KEY_STATE_UP:
        switch(key)
        {
        case KEY_VALUE_SHIFT:
            isShiftDown = 0;
        }
        break;
    }
}


友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: