diff -urN wf-/data.c wf/data.c --- wf-/data.c 2015-12-16 00:00:00.000000000 +0900 +++ wf/data.c 2015-12-17 00:00:00.000000000 +0900 @@ -43,9 +43,10 @@ static void bar_draw(pos_t *p2, prm_t *prm) { + pos_t wk[2]; data_t data = { type_wire_frame, - &(struct wire_frame){ 2, p2, (int[]){ 0,1,-1, -1 } } + &(struct wire_frame){ 2, p2, (int[]){ 0,1,-1, -1 }, wk } }; data_draw(&data, prm); } @@ -73,12 +74,13 @@ static void square_draw(prm_t *prm) { + pos_t wk[4]; 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 } } + (int[]){ 0,1,2,3,0,-1, -1 }, wk } }; data_draw(&data, prm); } @@ -86,6 +88,7 @@ static void cube_draw(prm_t *prm) { + pos_t wk[8]; data_t data = { type_wire_frame, &(struct wire_frame){ @@ -95,7 +98,7 @@ {-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 } } + 0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1, -1 }, wk } }; data_draw(&data, prm); } @@ -208,6 +211,17 @@ data_draw(data, prm); } +static void +op_data_slide_way(struct way *slide, data_t *data, prm_t *prm) +{ + affin_t af; + struct way way = *slide; + + way_get(&way, prm->sec); + affin_slide(&af, &way.ret_p); + 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) @@ -235,8 +249,6 @@ 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; @@ -287,6 +299,16 @@ case type_mirror: op_data_mirror(op->p, data, prm); break; + + case type_slide_way: + op_data_slide_way(op->p, data, prm); + break; +#if 0 + case type_rot_way: + op_data_rot_way(op->p, data, prm); + break; +#endif + case type_copy: op_data_copy(op->p, data, prm); break; diff -urN wf-/data.h wf/data.h --- wf-/data.h 2015-12-16 00:00:00.000000000 +0900 +++ wf/data.h 2015-12-17 00:00:00.000000000 +0900 @@ -2,6 +2,7 @@ #define __DATA_H__ #include "eye.h" +#include "way.h" typedef struct{ int type; @@ -25,6 +26,9 @@ #define type_point_symmetry 104 #define type_mirror 105 +#define type_slide_way 120 +#define type_rot_way 130 + #define type_copy 200 #define type_copy_rot 201 #define type_copy_point_symmetry 202 @@ -65,6 +69,7 @@ typedef struct{ affin_t af; const eye_t *eye; + double sec; } prm_t; void prm_set_eye_update(prm_t *prm, eye_t *eye); diff -urN wf-/Makefile wf/Makefile --- wf-/Makefile 2015-12-15 00:00:00.000000000 +0900 +++ wf/Makefile 2015-12-17 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 data.o eye.o d3.o x.o util.o key.o select.o +WF_OBJS = wf_ex.o data.o eye.o way.o d3.o x.o util.o key.o select.o all: wf_ex diff -urN wf-/way.c wf/way.c --- wf-/way.c 1970-01-01 09:00:00.000000000 +0900 +++ wf/way.c 2015-12-17 00:00:00.000000000 +0900 @@ -0,0 +1,152 @@ +#include +#include "way.h" + +static int +is_repeat(const double *ts, int n) +{ + return ts[ n-1 ] >= 0; +} + +static int +t_idx_rate(const double *ts, int n, double *t) +{ + /* t --> 0..1 , return idx */ + + int i; + double sum = 0; + + if(!is_repeat(ts, n)){ /* no repeat */ + if(*t < 0){ + *t = 0; + return 0; + } + for(i=0; i= sum){ + *t = 1; + return n-2; + } + }else{ /* repeat */ + for(i=0; i=sum) *t -= sum; + } + + sum = 0; + for(i=0; in; + const double *ts = way->ts; + int idx = t_idx_rate(ts, n, &t); + int nxt = (idx + 1) % n; + + if(way->dg == 1){ + if(way->vs){ + way->ret_v = linear(t, 0, ts[idx], way->vs[idx], way->vs[nxt]); + } + if(way->ps){ + line_t l; + line_set(&l, &way->ps[idx], &way->ps[nxt]); + line_pos(&l, t, &way->ret_p); + } + }else{ /* way->dg == 3 */ + int i, prv = (idx - 1 + n) % way->n; + + if(way->vs){ + double k[3], ks, ke, *ksp = &ks, *kep = &ke; + + for(i=0; i<3; i++) k[i] = way->vs[(idx+i)%n] - way->vs[(prv+i)%n]; + + if(!is_repeat(ts, n) && idx == 0) ksp = NULL; + else ks = ( k[0] * ts[idx] / ts[prv] + k[1] ) * 0.5; + + if(!is_repeat(ts, n) && idx == n-2) kep = NULL; + else ke = ( k[1] + k[2] * ts[idx] / ts[nxt] ) * 0.5; + + way->ret_v = interp3(way->vs[idx], way->vs[nxt], ksp, kep, t); + } + if(way->ps){ + vec_t k[3], ks, ke, *ksp = &ks, *kep = &ke; + + for(i=0; i<3; i++) vec_set(&k[i], &way->ps[(prv+i)%n], &way->ps[(idx+i)%n]); + + + if(!is_repeat(ts, n) && idx == 0) ksp = NULL; + else{ + ks = k[0]; + d3_mul(&ks, ts[idx] / ts[prv]); + d3_add(&ks, &k[1]); + d3_mul(&ks, 0.5); + } + + if(!is_repeat(ts, n) && idx == n-2) kep = NULL; + else{ + ke = k[2]; + d3_mul(&ke, ts[idx] / ts[nxt]); + d3_add(&ke, &k[1]); + d3_mul(&ke, 0.5); + } + + interp3_pos(&way->ps[idx], &way->ps[nxt], ksp, kep, t, &way->ret_p); + } + } +} + +double +interp3(double v0, double v1, const double *k0p, const double *k1p, double t_in) +{ +/* + v = at^3 + bt^2 + ct + d + k = 3at^2 + 2bt + c + t : 0 -> 1 + + v0 = d + k0 = c + v1 = a + b + c + d + k1 = 3a + 2b + c + + 3v1 = 3a + 3b + 3c + 3d + k1 = 3a + 2b + c + + 3v1 - k1 = b + 2c + 3d + b = 3v1 - k1 - 2c - 3d + = 3(v1 - d) - k1 - 2c + + ( b = 3(v1 - v0) - k1 - 2k0 ) + + v1 = a + b + c + d + a = v1 - b - c - d +*/ + + double k, k0, k1, a, b, c, d; + + k = v1 - v0; + k0 = k0p ? *k0p : k; + k1 = k1p ? *k1p : k; + if(!k0p) k0 = 2*k - k1; + if(!k1p) k1 = 2*k - k0; + + d = v0; + c = k0; + b = 3*(v1 - d) - k1 - 2*c; + a = v1 - b - c - d; + + return ((a * t_in + b) * t_in + c ) * t_in + d; +} + +void +interp3_pos(const pos_t *p0, const pos_t *p1, const vec_t *v0, const vec_t *v1, double t_in, pos_t *ret) +{ + ret->x = interp3(p0->x, p1->x, v0 ? &v0->x : NULL, v1 ? &v1->x : NULL, t_in); + ret->y = interp3(p0->y, p1->y, v0 ? &v0->y : NULL, v1 ? &v1->y : NULL, t_in); + ret->z = interp3(p0->z, p1->z, v0 ? &v0->z : NULL, v1 ? &v1->z : NULL, t_in); +} diff -urN wf-/way.h wf/way.h --- wf-/way.h 1970-01-01 09:00:00.000000000 +0900 +++ wf/way.h 2015-12-17 00:00:00.000000000 +0900 @@ -0,0 +1,42 @@ +#ifndef __INTERP_H__ +#define __INTERP_H__ + +#include "d3.h" + +/* + dobule vs[3] = { 1, 2, 3 }; + double ts[3] = { 2, 3, -1 }; + + v=1 -(2sec)-> v=2 -(3sec)-> v=3 stop + + dobule vs[3] = { 1, 2, 3 }; + double ts[3] = { 2, 3, 1 }; + + v=1 -(2sec)-> v=2 -(3sec)-> v=3 -(1sec)-> v=1(top) repeat + */ + +struct way{ + int n; + double *vs; + pos_t *ps; + + double *ts; + + int dg; /* degree 1 or 3 */ + + double ret_v; + pos_t ret_p; +}; + +void way_get(struct way *way, double t); + + +/* +interpolation +補間 +*/ + +double interp3(double v0, double v1, const double *k0p, const double *k1p, double t_in); +void interp3_pos(const pos_t *p0, const pos_t *p1, const vec_t *v0, const vec_t *v1, double t_in, pos_t *ret); + +#endif diff -urN wf-/wf_ex.c wf/wf_ex.c --- wf-/wf_ex.c 2015-12-16 00:00:00.000000000 +0900 +++ wf/wf_ex.c 2015-12-17 00:00:00.000000000 +0900 @@ -1,4 +1,5 @@ #include +#include #include "key.h" #include "x.h" #include "eye.h" @@ -30,7 +31,7 @@ eye_move(e, *mode, 'h', 1); break; default: - usleep(100*1000); + usleep(1*1000); break; } return 0; @@ -94,6 +95,14 @@ *op = -1; } +static double +now_sec(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec * 0.000001; +} + int main(int ac, char **av) { @@ -104,7 +113,8 @@ struct wire_frame wf; data_t data = { type_end, NULL }; prm_t prm; - + double start_sec; + cui_key_init(); cui_key_fd_add(0); cui_key_enter(); @@ -124,7 +134,8 @@ 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; + if((wf.t = malloc(sizeof(*wf.t) * wf.n)) == NULL) ERR("No Mem"); + data.type = type_wire_frame; data.p = &wf; } @@ -149,17 +160,36 @@ .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_t *cube = &(data_t){ type_op_data_set, &(struct op_data_set){ + .op = &(data_t){ type_slide_way, &(struct way){ + .n = 4, .vs = NULL, + .ps = (pos_t[]){{0,0,0},{0,10,0},{10,10,0},{10,0,0}}, + .ts = (double[]){3,2,1,2}, .dg = 1 }}, + .data = &(data_t){ type_cube } }}; + + data_t *cube2 = &(data_t){ type_op_data_set, &(struct op_data_set){ + .op = &(data_t){ type_slide_way, &(struct way){ + .n = 4, .vs = NULL, + .ps = (pos_t[]){{0,0,0},{0,10,0},{10,10,0},{10,0,0}}, + .ts = (double[]){1,1,1,1}, .dg = 3 }}, + .data = &(data_t){ type_cube } }}; + data.type = type_arr; data.p = (data_t[]){ *axyz, *cross, + *cube, *cube2, { type_end } }; } + start_sec = now_sec(); + while(key_work(&eye, &mode) != EOF){ xclear(); + prm.sec = now_sec() - start_sec; + if(mode % 2 == 1){ int x, y; for(y=0; y<2; y++){