Created
August 5, 2015 21:25
-
-
Save hiroshiro/b08a760b49947e974e69 to your computer and use it in GitHub Desktop.
関数プログラミングP58座標変換
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* coord.c | |
$ gcc -o coord coord.c -W -Wall -Wextra -lm -ansi -pedantic | |
$ ./coord | |
(-0.000000,-0.707107) | |
(-0.707107,0.000000) | |
(0.000000,0.707107) | |
(0.707107,-0.000000) | |
*/ | |
#include <stdio.h> | |
#include <math.h> | |
/* 座標の型 */ | |
typedef struct { | |
double x; | |
double y; | |
} coord_t; | |
/* 座標変換設定 */ | |
typedef struct { | |
coord_t rotAt; /* 回転中心座標 */ | |
double theta; /* 回転量[ラジアン] */ | |
double ofs_x; /* X軸方向平行移動量 */ | |
double ofs_y; /* Y軸方向平行移動量 */ | |
} config_t; | |
typedef coord_t (*converter_t)(coord_t); | |
/* 並行移動のプリミティブ */ | |
coord_t trans(double dx, double dy, coord_t coord) { | |
coord_t result = coord; | |
result.x += dx; | |
result.y += dy; | |
return result; | |
} | |
/* 原点中心回転のプリミティブ */ | |
coord_t rotate(double thela, coord_t coord) { | |
coord_t result = {0, 0}; | |
result.x = cos(thela) * coord.x - sin(thela) * coord.y; | |
result.y = sin(thela) * coord.x + cos(thela) * coord.y; | |
return result; | |
} | |
/* 設定を元にした並行移動 */ | |
coord_t trans_by_config(config_t config, coord_t coord) { | |
return trans(config.ofs_x, config.ofs_y, coord); | |
} | |
/* 設定を元にした回転 */ | |
coord_t rotate_by_config(config_t config, coord_t coord) { | |
coord_t pre_trans = trans(-config.rotAt.x, -config.rotAt.y, coord); | |
coord_t rotated = rotate(config.theta, pre_trans); | |
coord_t post_trans = trans(config.rotAt.x, config.rotAt.y, rotated); | |
return post_trans; | |
} | |
/* 設定を元にした座標変換 */ | |
coord_t convert_by_config(config_t config, coord_t coord) { | |
return trans_by_config(config, rotate_by_config(config, coord)); | |
} | |
/* 座標すべてに同じ変換を適用 */ | |
void map_to_coords(converter_t conv, size_t n, coord_t* in_coord, coord_t* out_coord) { | |
unsigned int i = 0; | |
for (i = 0; i < n; i++) out_coord[i] = conv(in_coord[i]); | |
} | |
int main(void) | |
{ | |
/* (0.5, 0.5)を中心に反時計回りに45度回転させ、(-0.5 -0.5)並列移動させる設定 */ | |
config_t config = { {0.5, 0.5}, 3.141592653589793 / 4, -0.5, -0.5 }; | |
/* 変換前の座標、たとえばこの4点からなる正方形 */ | |
coord_t unit_rect[] = { {0, 0}, {0, 1}, {1, 1}, {1, 0} }; | |
/* 変換後の座標 */ | |
coord_t converted_rect[] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} }; | |
/* map_to_coordsが使いたいが、 */ | |
/* convert_by_configと簡単には組み合わせられない */ | |
/* しかたないのでループ */ | |
{ unsigned int i = 0; | |
for (i = 0; i < sizeof(unit_rect)/sizeof(unit_rect[0]); i++) | |
converted_rect[i] = convert_by_config(config, unit_rect[i]); | |
} | |
{ unsigned int i = 0; | |
for (i = 0; i < sizeof(converted_rect)/sizeof(converted_rect[0]); i++) | |
printf("(%.6f,%.6f)\n", converted_rect[i].x, converted_rect[i].y); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment