#include #include #include #include #include "3d.h" #include "trig.h" #include "model.h" #define SQRT_3_4 .8660254037844386467637231707529361834714026269051903140279034897 #define SQRT_1_2 .707106781186547524400844362104849039284835937688474036588339869 /* * End of output from find-angle: # 63.43494882292173997484496795 f8 f0 2c 67 ac b7 4f 40 # 1.45106 1.45106 2.5091e-14 # 63.43494882292193892681098077 14 f1 2c 67 ac b7 4f 40 # 1.45106 1.45106 6.66134e-15 # 63.43494882292203840279398719 22 f1 2c 67 ac b7 4f 40 # 1.45106 1.45106 -3.33067e-15 # 63.43494882292198866480248398 1b f1 2c 67 ac b7 4f 40 # 1.45106 1.45106 8.88178e-16 # 63.43494882292200998108455678 1e f1 2c 67 ac b7 4f 40 # 1.45106 1.45106 -1.33227e-15 # 63.43494882292199577022984158 1c f1 2c 67 ac b7 4f 40 # 1.45106 1.45106 8.88178e-16 # 63.43494882292200287565719918 1d f1 2c 67 ac b7 4f 40 # 1.45106 1.45106 1.33227e-15 # 63.43494882292200998108455678 1e f1 2c 67 ac b7 4f 40 */ #define ANGLE 63.43494882292200998108455678 typedef struct solid SOLID; struct solid { PT3 *archetype; XFORM xf; PT3 at[8]; int locs[8]; int ox; } ; static PT3 arch_o[8]; static PT3 arch_a[8]; static SOLID solids[10]; static void gen_pts(double a, PT3 *pts) { double sa; double ca; double r; double d; double cg; double sg; PT3 cc; PT3 u; sa = sindeg(a); ca = cosdeg(a); pts[0] = (PT3){0,0,0}; pts[1] = (PT3){1,0,0}; pts[2] = (PT3){ca,sa,0}; pts[3] = add3(pts[1],pts[2]); cc = scale3(pts[3],.5); d = dist3(pts[0],cc); r = SQRT_3_4 * dist3(pts[1],pts[2]); // r² = 1² + d² - 2 × 1 × d × cos gamma // cos gamma = (1 + d² - r²) / (2 d) // we actually don't need gamma, just its sine cg = (1 + (d * d) - (r * r)) / (2 * d); if ((cg < -1) || (cg > 1)) abort(); sg = sqrt(1-(cg*cg)); u = unit3(pts[3]); pts[4] = (PT3){.x=cg*u.x,.y=cg*u.y,.z=sg}; pts[5] = add3(pts[4],pts[1]); pts[6] = add3(pts[4],pts[2]); pts[7] = add3(pts[4],pts[3]); } static void gen(double a) { gen_pts(a,&arch_a[0]); gen_pts(180-a,&arch_o[0]); } static int setup_point(MODEL *model, PT3 loc) { int lx; LOCATION *l; int px; POINT *p; lx = new_location(model); l = get_location(model,lx); l->l.x = loc.x; l->l.y = loc.y; l->l.z = loc.z; px = new_point(model); p = get_point(model,px); p->loc = lx; p->type = PT_CORNER; return(px); } static int add_triangle(MODEL *model, int *pta, int x1, int x2, int x3, int mx) { int tx; TRIANGLE *t; tx = new_triangle(model); t = get_triangle(model,tx); t->material = mx; t->corner[0] = pta[x1]; t->corner[1] = pta[x2]; t->corner[2] = pta[x3]; return(tx); } static int setup_object(MODEL *model, double rf, double gf, double bf, const char *name, int ptx[2]) { int ox; OBJECT *o; int mx; MATERIAL *m; mx = new_material(model); m = get_material(model,mx); m->name = strdup(name); m->selflum.r = .4 * rf; m->selflum.g = .4 * gf; m->selflum.b = .4 * bf; m->reflect.r = .8 * rf; m->reflect.g = .8 * gf; m->reflect.b = .8 * bf; m->spec_exp = 10; m->spec_mul = .5; ox = new_object(model); o = get_object(model,ox); o->ntriangles = 12; o->triangles = malloc(12*sizeof(int)); o->triangles[0] = add_triangle(model,ptx,0,1,3,mx); o->triangles[1] = add_triangle(model,ptx,0,3,2,mx); o->triangles[2] = add_triangle(model,ptx,0,2,6,mx); o->triangles[3] = add_triangle(model,ptx,0,6,4,mx); o->triangles[4] = add_triangle(model,ptx,0,4,5,mx); o->triangles[5] = add_triangle(model,ptx,0,5,1,mx); o->triangles[6] = add_triangle(model,ptx,7,3,1,mx); o->triangles[7] = add_triangle(model,ptx,7,1,5,mx); o->triangles[8] = add_triangle(model,ptx,7,5,4,mx); o->triangles[9] = add_triangle(model,ptx,7,4,6,mx); o->triangles[10] = add_triangle(model,ptx,7,6,2,mx); o->triangles[11] = add_triangle(model,ptx,7,2,3,mx); return(ox); } static void marker_triangle(MODEL *model, int p1, int p2, int p3) { int mx; MATERIAL *m; int ox; OBJECT *o; int tx; TRIANGLE *t; mx = new_material(model); m = get_material(model,mx); m->name = strdup("w"); m->selflum.r = .5; m->selflum.g = .5; m->selflum.b = .5; m->reflect.r = 0; m->reflect.g = 0; m->reflect.b = 0; m->spec_exp = 0; m->spec_mul = 0; ox = new_object(model); o = get_object(model,ox); o->ntriangles = 2; o->triangles = malloc(2*sizeof(int)); tx = new_triangle(model); t = get_triangle(model,tx); t->material = mx; t->corner[0] = p1; t->corner[1] = p2; t->corner[2] = p3; o->triangles[0] = tx; tx = new_triangle(model); t = get_triangle(model,tx); t->material = mx; t->corner[0] = p2; t->corner[1] = p1; t->corner[2] = p3; o->triangles[1] = tx; } static void transform_solid(SOLID *s) { int i; for (i=8-1;i>=0;i--) { s->at[i] = transform(s->archetype[i],s->xf); } } static void add_solid(MODEL *model, SOLID *s, const char *mname, double mr, double mg, double mb) { int i; for (i=8-1;i>=0;i--) s->locs[i] = setup_point(model,s->at[i]); s->ox = setup_object(model,mr,mg,mb,mname,&s->locs[0]); } static void gen_model(void) { MODEL *model; solids[0].archetype = &arch_o[0]; solids[0].xf = transform_identity(); transform_solid(&solids[0]); solids[1].archetype = &arch_o[0]; solids[1].xf = find_transform(solids[0].at[7],solids[0].at[5],solids[0].at[3]); transform_solid(&solids[1]); solids[5].archetype = &arch_a[0]; solids[5].xf = find_transform(solids[0].at[5],solids[0].at[7],solids[0].at[4]); transform_solid(&solids[5]); model = new_model(); add_solid(model,&solids[0],"r",1,0,0); add_solid(model,&solids[1],"g",0,1,0); add_solid(model,&solids[5],"b",0,0,1); (void)&marker_triangle; // marker_triangle(model,loca[1][0][1],loco2[0][0][1],loco[0][0][0]); save_model(model,stdout); } int main(void); int main(void) { gen(ANGLE); gen_model(); return(0); }