diff -ur wf-/data.c wf/data.c --- wf-/data.c 2016-01-17 00:00:00.000000000 +0900 +++ wf/data.c 2016-01-25 00:00:00.000000000 +0900 @@ -30,6 +30,7 @@ CASE_RET(type_zoom); CASE_RET(type_zoom_all); CASE_RET(type_zoom_and_slide); + CASE_RET(type_axis); CASE_RET(type_rot); CASE_RET(type_point_symmetry); CASE_RET(type_mirror); @@ -48,6 +49,7 @@ CASE_RET(type_train_way); CASE_RET(type_copy); CASE_RET(type_copy_rot); + CASE_RET(type_copy_domino); CASE_RET(type_copy_point_symmetry); CASE_RET(type_copy_mirror); CASE_RET(type_copy_timeshift); @@ -141,7 +143,7 @@ v2[0] = v; for(i=0; iaf, &prm->af, &af); + data_draw(data, prm); +} + +static void op_data_rot(struct rot *rot, data_t *data, prm_t *prm) { affin_t af; @@ -748,6 +762,37 @@ } static void +op_data_copy_domino(struct copy_domino *copy, data_t *data, prm_t *prm) +{ + int i; + struct curve *curve = ©->curve; + double ts[256]; + struct way way = { .n=curve->n, .ps=curve->ps, .ts=ts, .dg=3, .get_with_spd=1 }; + double t = copy->init; + + d3_t pos_spd[2]; + data_t op = { type_axis, pos_spd }; + + if(curve->n > 256) ERR("curve->n > 256"); + + for(i=0; in; i++){ + ts[i] = pos_distance(&curve->ps[i], &curve->ps[(i+1)%curve->n]); + } + if(!curve->closed) ts[curve->n-1] = -1; + + for(i=0; in; i++){ + way_get(&way, t); + + pos_spd[0] = way.ret_p; + pos_spd[1] = way.ret_spd_d3; + + op_data_draw(&op, data, prm); + + t += copy->step; + } +} + +static void op_data_copy_point_symmetry(d3_t *p, data_t *data, prm_t *prm) { data_t op = { type_point_symmetry, p }; @@ -856,6 +901,9 @@ case type_zoom_and_slide: op_data_zoom_and_slide(op->p, data, prm); break; + case type_axis: + op_data_axis(op->p, data, prm); + break; case type_rot: op_data_rot(op->p, data, prm); break; @@ -912,6 +960,9 @@ case type_copy_rot: op_data_copy_rot(op->p, data, prm); break; + case type_copy_domino: + op_data_copy_domino(op->p, data, prm); + break; case type_copy_point_symmetry: op_data_copy_point_symmetry(op->p, data, prm); break; diff -ur wf-/data.h wf/data.h --- wf-/data.h 2016-01-17 00:00:00.000000000 +0900 +++ wf/data.h 2016-01-25 00:00:00.000000000 +0900 @@ -35,6 +35,7 @@ #define type_zoom 101 #define type_zoom_all 140 #define type_zoom_and_slide 102 +#define type_axis 111 #define type_rot 103 #define type_point_symmetry 104 #define type_mirror 105 @@ -55,6 +56,7 @@ #define type_copy 200 #define type_copy_rot 201 +#define type_copy_domino 207 #define type_copy_point_symmetry 202 #define type_copy_mirror 203 #define type_copy_timeshift 204 @@ -181,6 +183,12 @@ /* deg = init_deg + step_deg * i */ }; +struct copy_domino{ + int n; + struct curve curve; + double init, step; /* distance */ +}; + struct copy_timeshift{ int n; double init_sec, step_sec; diff -ur wf-/way.c wf/way.c --- wf-/way.c 2016-01-13 00:00:00.000000000 +0900 +++ wf/way.c 2016-01-25 00:00:00.000000000 +0900 @@ -48,6 +48,9 @@ const double *ts = way->ts; int idx = way_idx_rate(ts, n, &t); int nxt = (idx + 1) % n; + int idx_spd = idx; + + if(way->get_with_spd) while(way->ts[idx_spd] <= 0) idx_spd = (idx_spd - 1 + n) % n; if(way->dg == 1){ if(way->vs){ @@ -58,6 +61,16 @@ line_set(&l, &way->ps[idx], &way->ps[nxt]); line_pos(&l, t, &way->ret_p); } + + if(way->get_with_spd){ + nxt = (idx_spd + 1) % n; + if(way->vs) way->ret_spd = way->vs[nxt] - way->vs[idx_spd]; + if(way->ps){ + way->ret_spd_d3 = way->ps[nxt]; + d3_sub(&way->ret_spd_d3, &way->ps[idx_spd]); + } + } + }else{ /* way->dg == 3 */ int i, prv = (idx - 1 + n) % way->n; @@ -72,7 +85,8 @@ if((!is_repeat(ts, n) && idx == n-2) || ts[nxt] == 0) 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); + interp3(way->vs[idx], way->vs[nxt], ksp, kep, t, + &way->ret_v, way->get_with_spd ? &way->ret_spd : NULL); } if(way->ps){ vec_t k[3], ks, ke, *ksp = &ks, *kep = &ke; @@ -96,9 +110,14 @@ d3_mul(&ke, 0.5); } - interp3_pos(&way->ps[idx], &way->ps[nxt], ksp, kep, t, &way->ret_p); + interp3_pos(&way->ps[idx], &way->ps[nxt], ksp, kep, t, + &way->ret_p, way->get_with_spd ? &way->ret_spd_d3 : NULL); } } + if(way->get_with_spd){ + if(way->vs) way->ret_spd /= way->ts[idx_spd]; + if(way->ps) d3_mul(&way->ret_spd_d3, 1.0 / way->ts[idx_spd]); + } } double @@ -186,11 +205,23 @@ { pos_t ps, pe; d3_t sec, init_sec; - int n = sscanf(s, "ps=(%lf,%lf,%lf),pe=(%lf,%lf,%lf),sec=(%lf,%lf,%lf),init_sec=(%lf,%lf,%lf)", - &ps.x, &ps.y, &ps.z, &pe.x, &pe.y, &pe.z, - &sec.x, &sec.y, &sec.z, &init_sec.x, &init_sec.y, &init_sec.z); - if(n != 12) ERR("n != 12"); + int n; + if((n = sscanf(s, "ps=(%lf,%lf,%lf),pe=(%lf,%lf,%lf),sec=(%lf,%lf,%lf),init_sec=(%lf,%lf,%lf)", + &ps.x, &ps.y, &ps.z, &pe.x, &pe.y, &pe.z, + &sec.x, &sec.y, &sec.z, &init_sec.x, &init_sec.y, &init_sec.z)) != 12){ + pos_t p; + double r, sec1, t; + if((n = sscanf(s, "p=(%lf,%lf,%lf),r=%lf,sec1=%lf,t=%lf", &p.x, &p.y, &p.z, &r, &sec1, &t)) != 6){ + if((n = sscanf(s, "p=(%lf,%lf,%lf)", &p.x, &p.y, &p.z)) != 3) ERR("foramat"); + r = 0; + sec1 = 1; + } + d3_set(&ps, p.x-r, p.y-r, p.z-r); + d3_set(&pe, p.x+r, p.y+r, p.z+r); + d3_set(&sec, t, t*(sec1+1)/sec1, t*(sec1+2)/sec1); + d3_set(&init_sec, 0,0,0); + } way_liss_init(wl, &ps, &pe, &sec, &init_sec); } @@ -208,8 +239,31 @@ } -double -interp3(double v0, double v1, const double *k0p, const double *k1p, double t_in) +void +interp3_abcd_get(double v0, double v1, const double *k0p, const double *k1p, + double *ret_a, double *ret_b, double *ret_c, double *ret_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; + + if(ret_a) *ret_a = a; + if(ret_b) *ret_b = b; + if(ret_c) *ret_c = c; + if(ret_d) *ret_d = d; +} + +void +interp3(double v0, double v1, const double *k0p, const double *k1p, double t_in, double *ret_v, double *ret_spd) { /* v = at^3 + bt^2 + ct + d @@ -234,26 +288,19 @@ 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; + double a, b, c, d; + interp3_abcd_get(v0, v1, k0p, k1p, &a, &b, &c, &d); + if(ret_v) *ret_v = ((a * t_in + b) * t_in + c ) * t_in + d; + if(ret_spd) *ret_spd = (3 * a * t_in + 2 * b) * t_in + c; } 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) +interp3_pos(const pos_t *p0, const pos_t *p1, const vec_t *v0, const vec_t *v1, double t_in, pos_t *ret, d3_t *ret_spd) { - 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); + interp3(p0->x, p1->x, v0 ? &v0->x : NULL, v1 ? &v1->x : NULL, t_in, + &ret->x, ret_spd ? &ret_spd->x : NULL); + interp3(p0->y, p1->y, v0 ? &v0->y : NULL, v1 ? &v1->y : NULL, t_in, + &ret->y, ret_spd ? &ret_spd->y : NULL); + interp3(p0->z, p1->z, v0 ? &v0->z : NULL, v1 ? &v1->z : NULL, t_in, + &ret->z, ret_spd ? &ret_spd->z : NULL); } diff -ur wf-/way.h wf/way.h --- wf-/way.h 2016-01-13 00:00:00.000000000 +0900 +++ wf/way.h 2016-01-25 00:00:00.000000000 +0900 @@ -24,8 +24,13 @@ int dg; /* degree 1 or 3 */ + int get_with_spd; + double ret_v; pos_t ret_p; + + double ret_spd; + d3_t ret_spd_d3; }; #define WAY_V2(v1,v2,t1,t2,dg_) { .n=2, .vs=(double[]){v1,v2}, .ts=(double[]){t1,t2}, .dg=dg_ } @@ -56,7 +61,9 @@ 補間 */ -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); +void interp3_abcd_get(double v0, double v1, const double *k0p, const double *k1p, + double *ret_a, double *ret_b, double *ret_c, double *ret_d); +void interp3(double v0, double v1, const double *k0p, const double *k1p, double t_in, double *ret_v, double *ret_spd); +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, d3_t *ret_spd); #endif diff -ur wf-/wf_ex.c wf/wf_ex.c --- wf-/wf_ex.c 2016-01-22 00:00:00.000000000 +0900 +++ wf/wf_ex.c 2016-01-25 00:00:00.000000000 +0900 @@ -142,7 +142,8 @@ int mode = 0; char *fn = opt_str("-fn", ac, av, NULL); struct wire_frame wf; - data_t data = { type_end }; + data_t arr[256], data = { type_arr, arr }; + int arr_i = 0; prm_t prm; cui_key_init(); @@ -166,12 +167,14 @@ grp_to_wf(&grp, &wf); wf.t = wf.v = NULL; - data.type = type_op_data_set; - data.p = &(struct op_data_set){ + arr[arr_i].type = type_op_data_set; + arr[arr_i].p = &(struct op_data_set){ .op = { type_rdiv_way, &(struct rdiv_way){ .n=4, .rate_way={.n=2,.vs=(double[]){0,0.2},.ts=(double[]){3,3},.dg=3} }}, .data = { type_wire_frame, &wf } }; + + arr_i++; } if(opt_idx("-demo", ac, av) > 0){ @@ -421,6 +424,16 @@ .op = { type_slide, &(d3_t){0,-4*a,-a*0.5} }, .data = { type_curve, &(struct curve){.n=rail->n,.ps=rail->ps,.closed=1,.div_n=0} } }}; + data_t *rail3 = &(data_t){ type_op_data_set, &(struct op_data_set){ + .op = { type_arr, (data_t[]){ + { type_slide, &(d3_t){0,-4*a,-a} }, + { type_copy_domino, &(struct copy_domino){ + .n=100, .curve={.n=rail->n,.ps=rail->ps,.closed=1,.div_n=0}, 0, 5 }}, + { type_zoom_all, (double[]){2} }, + { type_rot, &(struct rot){ .l=LINE_X, .deg=90 } }, + { type_end } }}, + .data = { type_square } }}; + data_t *matryoshka = &(data_t){ type_op_data_set, &(struct op_data_set){ .op = { type_arr, (data_t[]){ { type_slide, &(d3_t){20,20,20} }, @@ -519,23 +532,36 @@ { type_end } }}, .data = { type_cross, (pos_t[]){{-1,0,0},{1,0,0}} } }}; - data.type = type_arr; - data.p = (data_t[]){ - *axyz, - *cross, - *cube, *cube3, - *cup, *ferris_wheel, *merry_go_round, *ship, - *exile, *lissajours, - *half_pipe, - *fireworks, - *train, *rail1, *rail2, - *matryoshka, - *clock, - *ripple, *wave, *wave2, - { type_end } - }; + struct{ + char *key; + data_t *data; + }demos[] = { + { "-demo", (data_t[]){ *axyz, { type_end } } }, + { "-cross", (data_t[]){ *cross, { type_end } } }, + { "-cube", (data_t[]){ *cube, *cube3, { type_end } } }, + { "-park", (data_t[]){ *cup, *ferris_wheel, *merry_go_round, *ship, *exile, *lissajours, { type_end } } }, + { "-half_pipe", (data_t[]){ *half_pipe, { type_end } } }, + { "-fireworks", (data_t[]){ *fireworks, { type_end } } }, + { "-train", (data_t[]){ *train, { type_end } } }, + { "-rail", (data_t[]){ *rail1, *rail2, *rail3, { type_end } } }, + { "-matryoshka", (data_t[]){ *matryoshka, { type_end } } }, + { "-clock", (data_t[]){ *clock, { type_end } } }, + { "-ripple", (data_t[]){ *ripple, { type_end } } }, + { "-wave", (data_t[]){ *wave, { type_end } } }, + { "-wave2", (data_t[]){ *wave2, { type_end } } }, + { NULL, (data_t[]){ { type_end } } } + }, *dp = demos; + + for(; dp->key; dp++){ + data_t *p = dp->data; + if(opt_idx("-all", ac, av) <= 0 && opt_idx(dp->key, ac, av) <= 0) continue; + if(arr_i >= 256-1) ERR("arr_i >= 256-1"); + for(; p->type != type_end; p++) arr[arr_i++] = *p; + } } + arr[arr_i].type = type_end; + while(key_work(&eye, &mode) != EOF){ xclear();