Turbo Cを用いた2次元図形の幾何変換実装

2次元図形の幾何変換は、座標変換行列を用いた行列演算によって実現されます。本記事では、Turbo C環境下で平行移動、回転、拡大縮小、対称変換を実装する方法を解説します。各変換処理は、基準座標系を(540, 240)とし、三角形の頂点座標を変換して描画します。

回転処理

90度順時針回転を行列演算で実装します。以下はそのコード例です。

#include <stdio.h>
#include <graphics.h>
#include <math.h>

int baseX = 540;
int baseY = 240;
int vertex1_x = 540, vertex1_y = 240;
int vertex2_x = 650, vertex2_y = 150;
int vertex3_x = 560, vertex3_y = 120;

void drawTriangle() {
    line(vertex1_x, vertex1_y, vertex2_x, vertex2_y);
    line(vertex2_x, vertex2_y, vertex3_x, vertex3_y);
    line(vertex1_x, vertex1_y, vertex3_x, vertex3_y);
}

void rotate90Clockwise() {
    int rotationMatrix[3][3] = {{0, 1, 0}, {-1, 0, 0}, {0, 0, 1}};
    
    double relativeCoords[3][3] = {
        {0, 0, 1},
        {vertex2_x - baseX, vertex2_y - baseY, 1},
        {vertex3_x - baseX, vertex3_y - baseY, 1}
    };
    
    int transformed[3][2];
    
    for (int i = 0; i < 3; i++) {
        double x = 0.0, y = 0.0;
        for (int j = 0; j < 3; j++) {
            x += relativeCoords[i][j] * rotationMatrix[j][0];
            y += relativeCoords[i][j] * rotationMatrix[j][1];
        }
        transformed[i][0] = (int)x + baseX;
        transformed[i][1] = (int)y + baseY;
    }
    
    line(transformed[0][0], transformed[0][1], transformed[1][0], transformed[1][1]);
    line(transformed[1][0], transformed[1][1], transformed[2][0], transformed[2][1]);
    line(transformed[0][0], transformed[0][1], transformed[2][0], transformed[2][1]);
}

int main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "e:\\TC\\bgi");
    setcolor(4);
    setbkcolor(0);
    drawTriangle();
    rotate90Clockwise();
    getchar();
    closegraph();
    return 0;
}

平行移動処理

指定されたオフセット分だけ座標を移動します。以下は-100, -100の平移例です。

#include <stdio.h>
#include <graphics.h>

int baseX = 540;
int baseY = 240;
int vertex1_x = 540, vertex1_y = 240;
int vertex2_x = 650, vertex2_y = 150;
int vertex3_x = 560, vertex3_y = 120;

void drawTriangle() {
    line(vertex1_x, vertex1_y, vertex2_x, vertex2_y);
    line(vertex2_x, vertex2_y, vertex3_x, vertex3_y);
    line(vertex1_x, vertex1_y, vertex3_x, vertex3_y);
}

void translate() {
    int offsetX = -100;
    int offsetY = -100;
    int translationMatrix[3][3] = {{1, 0, 0}, {0, 1, 0}, {offsetX, offsetY, 1}};
    
    int coordinates[3][3] = {
        {vertex1_x, vertex1_y, 1},
        {vertex2_x, vertex2_y, 1},
        {vertex3_x, vertex3_y, 1}
    };
    
    int transformed[3][2];
    
    for (int i = 0; i < 3; i++) {
        transformed[i][0] = coordinates[i][0] * translationMatrix[0][0] +
                            coordinates[i][1] * translationMatrix[1][0] +
                            coordinates[i][2] * translationMatrix[2][0];
        transformed[i][1] = coordinates[i][0] * translationMatrix[0][1] +
                            coordinates[i][1] * translationMatrix[1][1] +
                            coordinates[i][2] * translationMatrix[2][1];
    }
    
    line(transformed[0][0], transformed[0][1], transformed[1][0], transformed[1][1]);
    line(transformed[1][0], transformed[1][1], transformed[2][0], transformed[2][1]);
    line(transformed[0][0], transformed[0][1], transformed[2][0], transformed[2][1]);
}

int main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "e:\\TC\\bgi");
    setcolor(4);
    setbkcolor(0);
    drawTriangle();
    translate();
    getchar();
    closegraph();
    return 0;
}

拡大縮小処理

スケーリング係数を用いて図形を拡大または縮小します。以下は0.5倍の縮小例です。

#include <stdio.h>
#include <graphics.h>
#include <math.h>

int baseX = 540;
int baseY = 240;
int vertex1_x = 540, vertex1_y = 240;
int vertex2_x = 650, vertex2_y = 150;
int vertex3_x = 560, vertex3_y = 120;

void drawTriangle() {
    line(vertex1_x, vertex1_y, vertex2_x, vertex2_y);
    line(vertex2_x, vertex2_y, vertex3_x, vertex3_y);
    line(vertex1_x, vertex1_y, vertex3_x, vertex3_y);
}

void scale() {
    double scale = 0.5;
    double scalingMatrix[3][3] = {{scale, 0, 0}, {0, scale, 0}, {0, 0, 1}};
    
    double relativeCoords[3][3] = {
        {0, 0, 1},
        {vertex2_x - baseX, vertex2_y - baseY, 1},
        {vertex3_x - baseX, vertex3_y - baseY, 1}
    };
    
    int transformed[3][2];
    
    for (int i = 0; i < 3; i++) {
        double x = 0.0, y = 0.0;
        for (int j = 0; j < 3; j++) {
            x += relativeCoords[i][j] * scalingMatrix[j][0];
            y += relativeCoords[i][j] * scalingMatrix[j][1];
        }
        transformed[i][0] = (int)x + baseX;
        transformed[i][1] = (int)y + baseY;
    }
    
    line(transformed[0][0], transformed[0][1], transformed[1][0], transformed[1][1]);
    line(transformed[1][0], transformed[1][1], transformed[2][0], transformed[2][1]);
    line(transformed[0][0], transformed[0][1], transformed[2][0], transformed[2][1]);
}

int main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "e:\\TC\\bgi");
    setcolor(4);
    setbkcolor(0);
    drawTriangle();
    scale();
    getchar();
    closegraph();
    return 0;
}

対称変換処理

y = x に関する対称変換を実装します。以下はそのコード例です。

#include <stdio.h>
#include <graphics.h>

int baseX = 540;
int baseY = 240;
int vertex1_x = 540, vertex1_y = 240;
int vertex2_x = 650, vertex2_y = 150;
int vertex3_x = 560, vertex3_y = 120;

void drawTriangle() {
    line(vertex1_x, vertex1_y, vertex2_x, vertex2_y);
    line(vertex2_x, vertex2_y, vertex3_x, vertex3_y);
    line(vertex1_x, vertex1_y, vertex3_x, vertex3_y);
}

void reflect() {
    int reflectionMatrix[3][3] = {{0, 1, 0}, {1, 0, 0}, {0, 0, 1}};
    
    double relativeCoords[3][3] = {
        {0, 0, 1},
        {vertex2_x - baseX, vertex2_y - baseY, 1},
        {vertex3_x - baseX, vertex3_y - baseY, 1}
    };
    
    int transformed[3][2];
    
    for (int i = 0; i < 3; i++) {
        double x = 0.0, y = 0.0;
        for (int j = 0; j < 3; j++) {
            x += relativeCoords[i][j] * reflectionMatrix[j][0];
            y += relativeCoords[i][j] * reflectionMatrix[j][1];
        }
        transformed[i][0] = (int)x + baseX;
        transformed[i][1] = (int)y + baseY;
    }
    
    line(transformed[0][0], transformed[0][1], transformed[1][0], transformed[1][1]);
    line(transformed[1][0], transformed[1][1], transformed[2][0], transformed[2][1]);
    line(transformed[0][0], transformed[0][1], transformed[2][0], transformed[2][1]);
}

int main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "e:\\TC\\bgi");
    setcolor(4);
    setbkcolor(0);
    drawTriangle();
    reflect();
    getchar();
    closegraph();
    return 0;
}

タグ: Turbo C C言語 BGI 行列演算 幾何変換

5月23日 11:02 投稿