diff -urN wf-/Makefile wf/Makefile --- wf-/Makefile 2015-12-12 00:00:00.000000000 +0900 +++ wf/Makefile 2015-12-15 00:00:00.000000000 +0900 @@ -3,7 +3,7 @@ LIBS = -lm -lX11 -L/usr/X11R6/lib CFLAGS += -Wall -I/usr/X11R6/include -WF_OBJS = wf_ex.o eye.o d3.o x.o util.o key.o select.o +WF_OBJS = wf_ex.o data.o eye.o d3.o x.o util.o key.o select.o all: wf_ex diff -urN wf-/d3.c wf/d3.c --- wf-/d3.c 2015-12-11 00:00:00.000000000 +0900 +++ wf/d3.c 2015-12-15 00:00:00.000000000 +0900 @@ -348,3 +348,262 @@ d3_add(p, &t.y); d3_add(p, &t.z); } + + +void +mat_trans(vec_t *x, vec_t *y, vec_t *z) +{ + vec_t tx, ty, tz; + + d3_set(&tx, x->x, y->x, z->x); + d3_set(&ty, x->y, y->y, z->y); + d3_set(&tz, x->z, y->z, z->z); + *x = tx; + *y = ty; + *z = tz; +} + +int +mat_rev(vec_t *x, vec_t *y, vec_t *z) +{ + vec_t tx, ty, tz; + double det = + x->x * y->y * z->z + + x->y * y->z * z->x + + x->z * y->x * z->y - + x->x * y->z * z->y - + x->z * y->y * z->x - + x->y * y->x * z->z; + double mul; + + if(det == 0) return -1; + + d3_set(&tx, + y->y * z->z - z->y * y->z, + z->y * x->z - x->y * z->z, + x->y * y->z - y->y * x->z); + d3_set(&ty, + z->x * y->z - y->x * z->z, + x->x * z->z - z->x * x->z, + y->x * x->z - x->x * y->z); + d3_set(&tz, + y->x * z->y - z->x * y->y, + z->x * x->y - x->x * z->y, + x->x * y->y - y->x * x->y); + *x = tx; + *y = ty; + *z = tz; + + mul = 1 / det; + d3_mul(x, mul); + d3_mul(y, mul); + d3_mul(z, mul); + return 0; +} + +void +mat_mul_d3(const vec_t *x, const vec_t *y, const vec_t *z, d3_t *d3) +{ +/* + d3.x + d3.y + d3.z + = + x.x y.x z.x + x.y y.y z.y + x.z y.z z.z + * + d3.x + d3.y + d3.z + */ + double bz = d3->z; + vec_t s = *x, t = *y; + + d3_mul(&s, d3->x); + d3_mul(&t, d3->y); + *d3 = *z; + d3_mul(d3, bz); + d3_add(d3, &s); + d3_add(d3, &t); +} + +void +mat_mul(vec_t *x, vec_t *y, vec_t *z, + const vec_t *x2, const vec_t *y2, const vec_t *z2) +{ +/* + x.x y.x z.x + x.y y.y z.y + x.z y.z z.z + = + x.x y.x z.x + x.y y.y z.y + x.z y.z z.z + * + x2.x y2.x z2.x + x2.y y2.y z2.y + x2.z y2.z z2.z + */ + vec_t tx = *x, ty = *y, tz = *z; + *x = *x2; + *y = *y2; + *z = *z2; + mat_mul_d3(&tx, &ty, &tz, x); + mat_mul_d3(&tx, &ty, &tz, y); + mat_mul_d3(&tx, &ty, &tz, z); +} + + +void +affin_init(affin_t *af) +{ + d3_set(&af->o, 0, 0, 0); + d3_set(&af->x, 1, 0, 0); + d3_set(&af->y, 0, 1, 0); + d3_set(&af->z, 0, 0, 1); +} + +void +affin_set(affin_t *af, const pos_t *o, const vec_t *x, const vec_t *y, const vec_t *z) +{ + af->o = *o; + af->x = *x; + af->y = *y; + af->z = *z; +} + +void +affin_set_axis(affin_t *af, const axis_t *ax) +{ + *af = *ax; +} + +int +affin_mat_rev(affin_t *af) +{ + int ret; + + if((ret = mat_rev(&af->x, &af->y, &af->z)) != 0) return ret; + return 0; +} + +void +affin_mat_mul_d3(const affin_t *af, d3_t *d3) +{ + mat_mul_d3(&af->x, &af->y, &af->z, d3); +} + +void +affin_mat_mul(affin_t *af, const affin_t *af2) +{ + mat_mul(&af->x, &af->y, &af->z, &af2->x, &af2->y, &af2->z); +} + +int +affin_rev(affin_t *af) +{ + int ret; + + if((ret = affin_mat_rev(af)) != 0) return ret; + affin_mat_mul_d3(af, &af->o); + d3_mul(&af->o, -1); + return 0; +} + +void +affin_compo(affin_t *ret_af, const affin_t *outside, const affin_t *inside) +{ + affin_t r = *outside; + + affin_mat_mul(&r, inside); + r.o = inside->o; + affin_conv(outside, &r.o); + *ret_af = r; +} + +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); +} + +void +affin_rconv(const affin_t *af, pos_t *p) +{ + affin_t rev = *af; + affin_rev(&rev); + axis_conv(&rev, p); +} + +void +affin_zoom_slide(affin_t *af, const d3_t *zoom, const d3_t *slide) +{ + affin_init(af); + af->x.x = zoom->x; + af->y.y = zoom->y; + af->z.z = zoom->z; + af->o = *slide; +} + +void +affin_slide(affin_t *af, const d3_t *slide) +{ + affin_init(af); + af->o = *slide; +} + +void +affin_zoom(affin_t *af, const d3_t *zoom) +{ + affin_init(af); + af->x.x = zoom->x; + af->y.y = zoom->y; + af->z.z = zoom->z; +} + +void +affin_axis_rconv(affin_t *af, const axis_t *ax) +{ + *af = *ax; +} + +void +affin_axis_conv(affin_t *af, const axis_t *ax) +{ + *af = *ax; + affin_rev(af); +} + +void +affin_rot_y(affin_t *af, double deg) +{ + double r, s, c; + + r = 2 * M_PI * deg / 360; + s = sin(r); + c = cos(r); + + affin_init(af); + af->z.z = af->x.z = c; + af->x.z = -s; + af->z.x = s; +} + +void +affin_rot(affin_t *af, const line_t *l, double deg) +{ + axis_t ax; + affin_t t; + + axis_set(&ax, &l->p, &l->v); + affin_axis_conv(af, &ax); + + affin_rot_y(&t, deg); + affin_compo(af, &t, af); + + affin_axis_rconv(&t, &ax); + affin_compo(af, &t, af); +} diff -urN wf-/d3.h wf/d3.h --- wf-/d3.h 2015-12-11 00:00:00.000000000 +0900 +++ wf/d3.h 2015-12-15 00:00:00.000000000 +0900 @@ -58,7 +58,7 @@ typedef struct{ pos_t o; vec_t x, y, z; -} axis_t; +} axis_t, affin_t; double pos_distance(const pos_t *a, const pos_t *b); @@ -83,4 +83,27 @@ void axis_conv(const axis_t *ax, pos_t *p); void axis_rconv(const axis_t *ax, pos_t *p); +void mat_trans(vec_t *x, vec_t *y, vec_t *z); +int mat_rev(vec_t *x, vec_t *y, vec_t *z); +void mat_mul_d3(const vec_t *x, const vec_t *y, const vec_t *z, d3_t *d3); +void mat_mul(vec_t *x, vec_t *y, vec_t *z, + const vec_t *x2, const vec_t *y2, const vec_t *z2); + +void affin_init(affin_t *af); +void affin_set(affin_t *af, const pos_t *o, const vec_t *x, const vec_t *y, const vec_t *z); +void affin_set_axis(affin_t *af, const axis_t *ax); +int affin_mat_rev(affin_t *af); +void affin_mat_mul(affin_t *af, const affin_t *af2); +int affin_rev(affin_t *af); +void affin_compo(affin_t *ret_af, const affin_t *outside, const affin_t *inside); +void affin_conv(const affin_t *af, pos_t *p); +void affin_rconv(const affin_t *af, pos_t *p); + +void affin_zoom_slide(affin_t *af, const d3_t *zoom, const d3_t *slide); +void affin_slide(affin_t *af, const d3_t *slide); +void affin_zoom(affin_t *af, const d3_t *zoom); +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); + #endif diff -urN wf-/data.c wf/data.c --- wf-/data.c 1970-01-01 09:00:00.000000000 +0900 +++ wf/data.c 2015-12-15 00:00:00.000000000 +0900 @@ -0,0 +1,168 @@ +#include "x.h" +#include "data.h" + +static void +wire_frame_draw(struct wire_frame *wf, prm_t *prm) +{ + int i, *op = wf->odr; + + if(!wf->t){ + if((wf->t = malloc(sizeof(*wf->t) * wf->n)) == NULL) ERR("No Mem"); + } + + for(i=0; in; i++){ + wf->t[i] = wf->p[i]; + affin_conv(&prm->af, &wf->t[i]); + } + + while(op[0] >= 0 && op[1] >= 0){ + pos_t p2[2]; + p2[0] = wf->t[ op[0] ]; + p2[1] = wf->t[ op[1] ]; + if(eye_clip(prm->eye, &p2[0], &p2[1]) >= 0){ + int x[2], y[2]; + eye_conv(prm->eye, &p2[0], &x[0], &y[0]); + eye_conv(prm->eye, &p2[1], &x[1], &y[1]); + if(x[0] != x[1] || y[0] != y[1]){ + xline(x[0], y[0], x[1], y[1]); + } + } + op++; + if(op[1] < 0) op += 2; + } +} + +static void +arr_draw(data_t *data, prm_t *prm) +{ + for(; data->type!=type_end; data++){ + data_draw(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_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_draw(&data, prm); +} + +static void +copy_draw(struct copy *copy, prm_t *prm) +{ + int x, y, z; + d3_t slide, n; + data_t data = { type_slide, &slide }; + + 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); + + data_draw(copy->org_data, prm); + *prm = bak; + } + } + } +} + + +static void +slide_draw(d3_t *slide, prm_t *prm) +{ + affin_t af; + affin_slide(&af, slide); + affin_compo(&prm->af, &prm->af, &af); +} + +static void +zoom_draw(d3_t *zoom, prm_t *prm) +{ + affin_t af; + affin_zoom(&af, zoom); + affin_compo(&prm->af, &prm->af, &af); +} + +static void +zoom_slide_draw(d3_t *d3, prm_t *prm) +{ + affin_t af; + affin_zoom_slide(&af, &d3[0], &d3[1]); + affin_compo(&prm->af, &prm->af, &af); +} + +static void +rot_draw(struct rot *rot, prm_t *prm) +{ + affin_t af; + affin_rot(&af, &rot->l, rot->deg); + affin_compo(&prm->af, &prm->af, &af); +} + +void +prm_set_eye_update(prm_t *prm, eye_t *eye) +{ + eye_update(eye); + prm->eye = eye; + affin_axis_conv(&prm->af, &eye->ax); +} + +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_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); + break; + + case type_slide: + slide_draw(data->p, prm); + break; + case type_zoom: + zoom_draw(data->p, prm); + break; + case type_zoom_slide: + zoom_slide_draw(data->p, prm); + break; + case type_rot: + rot_draw(data->p, prm); + default: + break; + } +} diff -urN wf-/data.h wf/data.h --- wf-/data.h 1970-01-01 09:00:00.000000000 +0900 +++ wf/data.h 2015-12-15 00:00:00.000000000 +0900 @@ -0,0 +1,55 @@ +#ifndef __DATA_H__ +#define __DATA_H__ + +#include "eye.h" + +typedef struct{ + int type; + void *p; +} data_t, op_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 DP(type, ...) (type[]){ __VA_ARGS__ } + +struct wire_frame{ + int n; /* ex. n = 4 */ + pos_t *p; /* ex. p = (pos_t[]){ {0,0,0},{1,0,0},{1,1,0},{0,1,0} } */ + int *odr; /* ex. odr = (int[]){ 0,1,2,3,0,-1, 0,2,-1, 1,3,-1, -1 } */ + + /* work */ + pos_t *t; +}; + +struct copy{ + struct { int x, y, z; } n; + d3_t init, step; + /* slide = init + step * i */ + + data_t *org_data; +}; + +struct rot{ + line_t l; + double deg; +}; + +typedef struct{ + affin_t af; + const eye_t *eye; +} prm_t; + +void prm_set_eye_update(prm_t *prm, eye_t *eye); +void data_draw(data_t *data, prm_t *prm); + +#endif diff -urN wf-/wf_ex.c wf/wf_ex.c --- wf-/wf_ex.c 2015-12-13 00:00:00.000000000 +0900 +++ wf/wf_ex.c 2015-12-15 00:00:00.000000000 +0900 @@ -2,6 +2,7 @@ #include "key.h" #include "x.h" #include "eye.h" +#include "data.h" static int key_work(eye_t *e, int *mode) @@ -35,21 +36,6 @@ return 0; } -void -draw_line(const eye_t *e, const pos_t *p) -{ - pos_t p2[2]; - int i, x[2], y[2]; - - p2[0] = p[0]; - p2[1] = p[1]; - for(i=0; i<2; i++) axis_conv(&e->ax, &p2[i]); - if(eye_clip(e, &p2[0], &p2[1]) < 0) return; - for(i=0; i<2; i++) eye_conv(e, &p2[i], &x[i], &y[i]); - if(x[0] == x[1] && y[0] == y[1]) return; - xline(x[0], y[0], x[1], y[1]); -} - struct grp{ int w, h; pos_t *p; @@ -80,26 +66,32 @@ } static void -draw_grp(const eye_t *e, const struct grp *g) +grp_to_wf(const struct grp *g, struct wire_frame *wf) { - int x, y, i; - pos_t p2[2]; + int odr_n, x, y, i, *op; + + wf->n = g->w * g->h; + wf->p = g->p; + + odr_n = (g->w + 1) * g->h + (g->h + 1) * g->w + 1; + if((wf->odr = malloc(sizeof(*wf->odr) * odr_n)) == NULL) ERR("No Mem"); + op = wf->odr; for(y=0; yh; y++){ for(x=0; xw; x++){ - i = g->w * y + x; - if(x < g->w-1){ - p2[0] = g->p[i]; - p2[1] = g->p[i+1]; - draw_line(e, p2); - } - if(y < g->h-1){ - p2[0] = g->p[i]; - p2[1] = g->p[i+g->w]; - draw_line(e, p2); - } + i = y * g->w + x; + *op++ = i; + } + *op++ = -1; + } + for(x=0; xw; x++){ + for(y=0; yh; y++){ + i = y * g->w + x; + *op++ = i; } + *op++ = -1; } + *op = -1; } int @@ -113,6 +105,9 @@ d3_t zoom; struct grp grp; double t; + struct wire_frame wf; + data_t data = { type_wire_frame, &wf }; + prm_t prm; if(!fn) ERR("-fn filename"); sscanf(zoom_s, "%lf,%lf,%lf", &zoom.x, &zoom.y, &zoom.z); @@ -130,9 +125,10 @@ d3_set(&eye.p, 0, -t, t); d3_set(&eye.t, t/2, t/2, 0); - while(key_work(&eye, &mode) != EOF){ - eye_update(&eye); + grp_to_wf(&grp, &wf); + wf.t = NULL; + while(key_work(&eye, &mode) != EOF){ xclear(); if(mode % 2 == 1){ @@ -143,12 +139,13 @@ eye_set_div4(&e, x, y); if(y == 0) eye_move(&e, 0, 'v', 45 / e.move_deg); if(x != 0) eye_move(&e, 0, 'h', 45 / e.move_deg); - eye_update(&e); - draw_grp(&e, &grp); + prm_set_eye_update(&prm, &e); + data_draw(&data, &prm); } } }else{ - draw_grp(&eye, &grp); + prm_set_eye_update(&prm, &eye); + data_draw(&data, &prm); } if(mode / 2 == 1) xrect(1, 1, w-2, h-2);