Skip to content

Instantly share code, notes, and snippets.

@hiroshiro
Created August 5, 2015 21:25
Show Gist options
  • Save hiroshiro/b08a760b49947e974e69 to your computer and use it in GitHub Desktop.
Save hiroshiro/b08a760b49947e974e69 to your computer and use it in GitHub Desktop.
関数プログラミングP58座標変換
/* 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