192ceb 2003-11-22 Henrik Grubbström (Grubba) //! Graph sub-module providing draw functions. //! 7b62e2 2011-04-25 Martin Stjernholm //! \$Id\$ d697d7 1999-09-30 Henrik Wallin a580e1 2000-09-27 Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__ a20af6 2000-09-26 Fredrik Hübinette (Hubbe) d697d7 1999-09-30 Henrik Wallin #define CAP_BUTT 0 #define CAP_ROUND 1 #define CAP_PROJECTING 2 #define JOIN_MITER 0 #define JOIN_ROUND 1 #define JOIN_BEVEL 2 #define CAPSTEPS 10 #define JOINSTEPS 5 constant PI = 3.1415926535897932384626433832795080; /* * Some optimizations for the cappings. * 192ceb 2003-11-22 Henrik Grubbström (Grubba) * /grubba (who got tired of BG being so slow) d697d7 1999-09-30 Henrik Wallin */ static array(float) init_cap_sin_table() { array(float) s_t = allocate(CAPSTEPS); for (int i = 0; i < CAPSTEPS; i++) { s_t[i] = sin(PI*i/(CAPSTEPS-1)); } 18096f 2003-08-22 Martin Nilsson return s_t; d697d7 1999-09-30 Henrik Wallin } static array(float) cap_sin_table = init_cap_sin_table(); static array(float) init_cap_cos_table() { array(float) c_t = allocate(CAPSTEPS); for (int i = 0; i < CAPSTEPS; i++) { c_t[i] = cos(PI*i/(CAPSTEPS-1)); } 18096f 2003-08-22 Martin Nilsson return c_t; d697d7 1999-09-30 Henrik Wallin } static array(float) cap_cos_table = init_cap_cos_table(); static private array(float) xyreverse(array(float) a) { array(float) r = reverse(a); int n = sizeof(r)/2; while(n--) { float t = r[n<<1]; r[n<<1] = r[(n<<1)+1]; r[(n<<1)+1] = t; } return r; } array(array(float)) make_polygon_from_line(float h, array(float) coords, int|void cap_style, int|void join_style) { int points = sizeof(coords)/2; int closed = points>2 && coords[0] == coords[(points-1)<<1] && coords[1] == coords[((points-1)<<1)+1]; if(closed) --points; int point; float sx = h/2, sy = 0.0; array(float) left = ({ }), right = ({ }); for(point=0; point 0.0) { sx = (-dy*h) / (dd*2); sy = (dx*h) / (dd*2); } if(point == 0 && !closed) { /* Initial cap */ switch(cap_style) { case CAP_BUTT: left += ({ ox+sx, oy+sy }); right += ({ ox-sx, oy-sy }); break; case CAP_PROJECTING: left += ({ ox+sx-sy, oy+sy+sx }); right += ({ ox-sx-sy, oy-sy+sx }); break; case CAP_ROUND: array(float) initial_cap = allocate(CAPSTEPS*2); int j=0; for(int i=0; i 0.0) { s2x = (-d2y*h) / (d2d*2); s2y = (d2x*h) / (d2d*2); } else { s2x = sx; s2y = sy; } float mdiv = (sx*s2y-sy*s2x); if(mdiv == 0.0) { left += ({ tx+sx, ty+sy, tx+s2x, ty+s2y }); right += ({ tx-sx, ty-sy, tx-s2x, ty-s2y }); } else { float m = (s2y*(sy-s2y)+s2x*(sx-s2x))/mdiv; /* Left join */ switch(mdiv<0.0 && join_style) { case JOIN_MITER: left += ({ tx+sx+sy*m, ty+sy-sx*m }); break; case JOIN_BEVEL: left += ({ tx+sx, ty+sy, tx+s2x, ty+s2y }); break; case JOIN_ROUND: float theta0 = acos((sx*s2x+sy*s2y)/(sx*sx+sy*sy)); for(int i=0; i0.0 && join_style) { case JOIN_MITER: right += ({ tx-sx-sy*m, ty-sy+sx*m }); break; case JOIN_BEVEL: right += ({ tx-sx, ty-sy, tx-s2x, ty-s2y }); break; case JOIN_ROUND: float theta0 = -acos((sx*s2x+sy*s2y)/(sx*sx+sy*sy)); for(int i=0; i