diff -urN wf-/d3.c wf/d3.c --- wf-/d3.c 2015-12-15 00:00:00.000000000 +0900 +++ wf/d3.c 2015-12-16 00:00:00.000000000 +0900 @@ -525,7 +525,6 @@ void affin_conv(const affin_t *af, pos_t *p) { - //axis_rconv(af, p); affin_mat_mul_d3(af, p); d3_add(p, &af->o); } @@ -535,7 +534,7 @@ { affin_t rev = *af; affin_rev(&rev); - axis_conv(&rev, p); + affin_conv(&rev, p); } void @@ -587,7 +586,7 @@ c = cos(r); affin_init(af); - af->z.z = af->x.z = c; + af->z.z = af->x.x = c; af->x.z = -s; af->z.x = s; } @@ -607,3 +606,28 @@ affin_axis_rconv(&t, &ax); affin_compo(af, &t, af); } + +void +affin_point_symmetry(affin_t *af, const pos_t *p) +{ + affin_t t, s; + vec_t x = {-1,0,0}, y = {0,-1,0}, z = {0,0,-1}; + + affin_set(&t, p, &x, &y, &z); + affin_rev(&t); + affin_slide(&s, p); + affin_compo(af, &s, &t); +} + +void +affin_mirror(affin_t *af, const plane_t *pl) +{ + axis_t ax; + affin_t t; + d3_t zoom = {0,-1,0}; + + axis_set(&ax, &pl->p, &pl->v); + affin_axis_conv(af, &ax); + affin_zoom_slide(&t, &zoom, &pl->p); + affin_compo(af, &t, af); +} diff -urN wf-/d3.h wf/d3.h --- wf-/d3.h 2015-12-15 00:00:00.000000000 +0900 +++ wf/d3.h 2015-12-16 00:00:00.000000000 +0900 @@ -105,5 +105,7 @@ void affin_axis_rconv(affin_t *af, const axis_t *ax); void affin_axis_conv(affin_t *af, const axis_t *ax); void affin_rot(affin_t *af, const line_t *l, double deg); +void affin_point_symmetry(affin_t *af, const pos_t *p); +void affin_mirror(affin_t *af, const plane_t *pl); #endif diff -urN wf-/data.c wf/data.c --- wf-/data.c 2015-12-15 00:00:00.000000000 +0900 +++ wf/data.c 2015-12-16 00:00:00.000000000 +0900 @@ -1,6 +1,14 @@ #include "x.h" #include "data.h" +void +prm_set_eye_update(prm_t *prm, eye_t *eye) +{ + eye_update(eye); + prm->eye = eye; + affin_axis_conv(&prm->af, &eye->ax); +} + static void wire_frame_draw(struct wire_frame *wf, prm_t *prm) { @@ -33,136 +41,268 @@ } static void -arr_draw(data_t *data, prm_t *prm) +bar_draw(pos_t *p2, prm_t *prm) { - for(; data->type!=type_end; data++){ - data_draw(data, prm); - } + data_t data = { + type_wire_frame, + &(struct wire_frame){ 2, p2, (int[]){ 0,1,-1, -1 } } + }; + data_draw(&data, prm); +} + +static void +cross_draw(pos_t *p2, prm_t *prm) +{ + data_t data = { type_bar, p2 }; + pos_t o; + vec_t v; + axis_t ax; + struct rot rot = { .deg = 90 }; + data_t op = { type_rot, &rot }; + + data_draw(&data, prm); + + d3_cen(&o, &p2[0], &p2[1]); + vec_set(&v, &p2[0], &p2[1]); + axis_set(&ax, &o, &v); + rot.l.p = o; + rot.l.v = ax.z; + op_data_draw(&op, &data, prm); } static void square_draw(prm_t *prm) { - data_t data = { type_wire_frame, DP(struct wire_frame, { - 4, - (pos_t[]){ {-1,-1,0},{1,-1,0},{1,1,0},{-1,1,0} }, - (int[]){ 0,1,2,3,0,-1, -1 }, - } ) }; + data_t data = { + type_wire_frame, + &(struct wire_frame){ + 4, + (pos_t[]){ {-1,-1,0},{1,-1,0},{1,1,0},{-1,1,0} }, + (int[]){ 0,1,2,3,0,-1, -1 } } + }; data_draw(&data, prm); } static void cube_draw(prm_t *prm) { - data_t data = { type_wire_frame, DP(struct wire_frame, { - 8, - (pos_t[]){ - {-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1}, - {-1,-1,1},{1,-1,1},{1,1,1},{-1,1,1} }, - (int[]){ - 0,1,2,3,0,-1, 4,5,6,7,4,-1, - 0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1, -1 }, - } ) }; + data_t data = { + type_wire_frame, + &(struct wire_frame){ + 8, + (pos_t[]){ + {-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1}, + {-1,-1,1},{1,-1,1},{1,1,1},{-1,1,1} }, + (int[]){ + 0,1,2,3,0,-1, 4,5,6,7,4,-1, + 0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1, -1 } } + }; data_draw(&data, prm); } static void -copy_draw(struct copy *copy, prm_t *prm) +arr_draw(data_t *data, prm_t *prm) { - int x, y, z; - d3_t slide, n; - data_t data = { type_slide, &slide }; + for(; data->type!=type_end; data++){ + data_draw(data, prm); + } +} - for(z=0; zn.z; z++){ - for(y=0; yn.y; y++){ - for(x=0; xn.x; x++){ - prm_t bak = *prm; - slide = copy->step; - d3_set(&n, x, y, z); - d3_zoom(&slide, &n); - d3_add(&slide, ©->init); - data_draw(&data, prm); +static void +op_data_set_draw(struct op_data_set *set, prm_t *prm) +{ + op_data_draw(set->op, set->data, prm); +} - data_draw(copy->org_data, prm); - *prm = bak; - } - } +void +data_draw(data_t *data, prm_t *prm) +{ + switch(data->type){ + case type_wire_frame: + wire_frame_draw(data->p, prm); + break; + case type_bar: + bar_draw(data->p, prm); + break; + case type_cross: + cross_draw(data->p, prm); + break; + case type_square: + square_draw(prm); + break; + case type_cube: + cube_draw(prm); + break; + + case type_arr: + arr_draw(data->p, prm); + break; + case type_op_data_set: + op_data_set_draw(data->p, prm); + + case type_end: + default: + break; } } +static void +op_data_arr(data_t *op_arr, data_t *data, prm_t *prm) +{ + struct op_data_set set = { &op_arr[1], data }; + data_t d = { type_op_data_set, &set }; + op_data_draw(&op_arr[0], &d, prm); +} static void -slide_draw(d3_t *slide, prm_t *prm) +op_data_slide(d3_t *slide, data_t *data, prm_t *prm) { affin_t af; affin_slide(&af, slide); affin_compo(&prm->af, &prm->af, &af); + data_draw(data, prm); } static void -zoom_draw(d3_t *zoom, prm_t *prm) +op_data_zoom(d3_t *zoom, data_t *data, prm_t *prm) { affin_t af; affin_zoom(&af, zoom); affin_compo(&prm->af, &prm->af, &af); + data_draw(data, prm); } static void -zoom_slide_draw(d3_t *d3, prm_t *prm) +op_data_zoom_and_slide(d3_t *d3, data_t *data, prm_t *prm) { affin_t af; affin_zoom_slide(&af, &d3[0], &d3[1]); affin_compo(&prm->af, &prm->af, &af); + data_draw(data, prm); } static void -rot_draw(struct rot *rot, prm_t *prm) +op_data_rot(struct rot *rot, data_t *data, prm_t *prm) { affin_t af; affin_rot(&af, &rot->l, rot->deg); affin_compo(&prm->af, &prm->af, &af); + data_draw(data, prm); } -void -prm_set_eye_update(prm_t *prm, eye_t *eye) +static void +op_data_point_symmetry(d3_t *p, data_t *data, prm_t *prm) { - eye_update(eye); - prm->eye = eye; - affin_axis_conv(&prm->af, &eye->ax); + affin_t af; + affin_point_symmetry(&af, p); + affin_compo(&prm->af, &prm->af, &af); + data_draw(data, prm); +} + +static void +op_data_mirror(plane_t *pl, data_t *data, prm_t *prm) +{ + affin_t af; + affin_mirror(&af, pl); + affin_compo(&prm->af, &prm->af, &af); + data_draw(data, prm); +} + + +static void +op_data_copy(struct copy *copy, data_t *data, prm_t *prm) +{ + int x, y, z; + d3_t slide; + data_t op = { type_slide, &slide }; + + for(z=0; zn.z; z++){ + for(y=0; yn.y; y++){ + for(x=0; xn.x; x++){ + d3_set(&slide, x, y, z); + d3_zoom(&slide, ©->step); + d3_add(&slide, ©->init); + op_data_draw(&op, data, prm); + } + } + } +} + +static void +op_data_copy_rot(struct copy_rot *copy, data_t *data, prm_t *prm) +{ + int i; + struct rot rot = { copy->l, copy->init_deg }; + data_t op = { type_rot, &rot }; + +data_draw(data, prm); + + for(i=0; in; i++){ + op_data_draw(&op, data, prm); + rot.deg += copy->step_deg; + } +} + +static void +op_data_copy_point_symmetry(d3_t *p, data_t *data, prm_t *prm) +{ + data_t op = { type_point_symmetry, p }; + data_draw(data, prm); + op_data_draw(&op, data, prm); +} + +static void +op_data_copy_mirror(plane_t *pl, data_t *data, prm_t *prm) +{ + data_t op = { type_mirror, pl }; + data_draw(data, prm); + op_data_draw(&op, data, prm); } void -data_draw(data_t *data, prm_t *prm) +op_data_draw(data_t *op, data_t *data, prm_t *prm) { - switch(data->type){ - case type_wire_frame: - wire_frame_draw(data->p, prm); - break; + prm_t bak = *prm; + + switch(op->type){ case type_arr: - arr_draw(data->p, prm); - break; - case type_copy: - copy_draw(data->p, prm); - break; - case type_square: - square_draw(prm); - break; - case type_cube: - cube_draw(prm); + op_data_arr(op->p, data, prm); break; case type_slide: - slide_draw(data->p, prm); + op_data_slide(op->p, data, prm); break; case type_zoom: - zoom_draw(data->p, prm); + op_data_zoom(op->p, data, prm); break; - case type_zoom_slide: - zoom_slide_draw(data->p, prm); + case type_zoom_and_slide: + op_data_zoom_and_slide(op->p, data, prm); break; case type_rot: - rot_draw(data->p, prm); + op_data_rot(op->p, data, prm); + break; + case type_point_symmetry: + op_data_point_symmetry(op->p, data, prm); + break; + case type_mirror: + op_data_mirror(op->p, data, prm); + break; + case type_copy: + op_data_copy(op->p, data, prm); + break; + case type_copy_rot: + op_data_copy_rot(op->p, data, prm); + break; + case type_copy_point_symmetry: + op_data_copy_point_symmetry(op->p, data, prm); + break; + case type_copy_mirror: + op_data_copy_mirror(op->p, data, prm); + break; + + case type_end: default: break; } + *prm = bak; } diff -urN wf-/data.h wf/data.h --- wf-/data.h 2015-12-15 00:00:00.000000000 +0900 +++ wf/data.h 2015-12-16 00:00:00.000000000 +0900 @@ -6,21 +6,30 @@ typedef struct{ int type; void *p; -} data_t, op_t; +} data_t; -#define type_end (-1) -#define type_wire_frame 0 -#define type_arr 1 -#define type_copy 2 -#define type_square 3 -#define type_cube 4 - -#define type_slide 100 -#define type_zoom 101 -#define type_zoom_slide 102 -#define type_rot 110 +#define type_end (-1) +#define type_wire_frame 0 +#define type_bar 1 +#define type_cross 2 +#define type_square 3 +#define type_cube 4 + +#define type_arr 10 +#define type_op_data_set 11 + +#define type_slide 100 +#define type_zoom 101 +#define type_zoom_and_slide 102 +#define type_rot 103 +#define type_point_symmetry 104 +#define type_mirror 105 + +#define type_copy 200 +#define type_copy_rot 201 +#define type_copy_point_symmetry 202 +#define type_copy_mirror 203 -#define DP(type, ...) (type[]){ __VA_ARGS__ } struct wire_frame{ int n; /* ex. n = 4 */ @@ -31,17 +40,26 @@ pos_t *t; }; +struct op_data_set{ + data_t *op, *data; +}; + +struct rot{ + line_t l; + double deg; +}; + struct copy{ struct { int x, y, z; } n; d3_t init, step; /* slide = init + step * i */ - - data_t *org_data; }; -struct rot{ +struct copy_rot{ + int n; line_t l; - double deg; + double init_deg, step_deg; + /* deg = init_deg + step_deg * i */ }; typedef struct{ @@ -51,5 +69,6 @@ void prm_set_eye_update(prm_t *prm, eye_t *eye); void data_draw(data_t *data, prm_t *prm); +void op_data_draw(data_t *op, data_t *data, prm_t *prm); #endif diff -urN wf-/wf_ex.c wf/wf_ex.c --- wf-/wf_ex.c 2015-12-15 00:00:00.000000000 +0900 +++ wf/wf_ex.c 2015-12-16 00:00:00.000000000 +0900 @@ -101,18 +101,10 @@ eye_t eye; int mode = 0; char *fn = opt_str("-fn", ac, av, NULL); - char *zoom_s = opt_str("-zoom", ac, av, "1,1,1"); - d3_t zoom; - struct grp grp; - double t; struct wire_frame wf; - data_t data = { type_wire_frame, &wf }; + data_t data = { type_end, NULL }; prm_t prm; - if(!fn) ERR("-fn filename"); - sscanf(zoom_s, "%lf,%lf,%lf", &zoom.x, &zoom.y, &zoom.z); - grp_read(&grp, fopen(fn, "r"), &zoom); - cui_key_init(); cui_key_fd_add(0); cui_key_enter(); @@ -121,12 +113,49 @@ if(opt_idx("-ximg", ac, av) > 0) ximg_curr = ximg_alloc(); eye_init(&eye, w, h); - t = grp.h * zoom.y; - d3_set(&eye.p, 0, -t, t); - d3_set(&eye.t, t/2, t/2, 0); + d3_set(&eye.p, 0, -4, 4); + d3_set(&eye.t, 2, 2, 0); - grp_to_wf(&grp, &wf); - wf.t = NULL; + if(fn){ + char *zoom_s = opt_str("-zoom", ac, av, "1,1,1"); + d3_t zoom; + struct grp grp; + + sscanf(zoom_s, "%lf,%lf,%lf", &zoom.x, &zoom.y, &zoom.z); + grp_read(&grp, fopen(fn, "r"), &zoom); + grp_to_wf(&grp, &wf); + wf.t = NULL; + data.type = type_wire_frame; + data.p = &wf; + } + + if(opt_idx("-demo", ac, av) > 0){ + + data_t *ax = &(data_t){ type_arr, (data_t[]){ + { type_op_data_set, &(struct op_data_set){ + .op = &(data_t){ type_copy, &(struct copy){ + .n = {200,1,1}, .init = {-100,0,0}, .step = {1,0,0} }}, + .data = &(data_t){ type_bar, (pos_t[]){{0,0,0},{0,1,0}} } }}, + { type_bar, (pos_t[]){{-100,0,0},{100,0,0}} }, + { type_end } }}; + + data_t *axyz = &(data_t){ type_op_data_set, &(struct op_data_set){ + .op = &(data_t){ type_copy_rot, &(struct copy_rot){ + .n = 3, .l = {{0,0,0},{1,1,1}}, .init_deg = 0, .step_deg = 120 }}, + .data = ax }}; + + data_t *cross = &(data_t){ type_op_data_set, &(struct op_data_set){ + .op = &(data_t){ type_copy, &(struct copy){ + .n = {5*2+1,4*2+1,2*2+1}, .init = {-20*5,-30*4,-40*2}, .step = {20,30,40} }}, + .data = &(data_t){ type_cross, (pos_t[]){{-4,0,0},{4,0,0}} } }}; + + data.type = type_arr; + data.p = (data_t[]){ + *axyz, + *cross, + { type_end } + }; + } while(key_work(&eye, &mode) != EOF){ xclear(); @@ -147,7 +176,7 @@ prm_set_eye_update(&prm, &eye); data_draw(&data, &prm); } - if(mode / 2 == 1) xrect(1, 1, w-2, h-2); + if(mode / 2 == 1) xrect(4, 4, w-1-4, h-1-4); xflush(); if(ximg_curr) ximg_put();