//========================================================================================== // arc_bulge.txt // Author: Clif Collins Date: Jan 2010 //========================================================================================== //========================================================================================== // arcToBulge // here bulge = sweep, AutoCAD bulge = tan(sweep / 2) //========================================================================================== function arcToBulge(arc) { var bul,start,sweep,ds; bul = new Object(); x = arc.radius; start = arc.start / 180 * Math.PI; sweep = arc.sweep / 180 * Math.PI; bul.x1 = (x * Math.cos(start)) + arc.cx; bul.y1 = (x * Math.sin(start)) + arc.cy; bul.x2 = (x * Math.cos(start+sweep)) + arc.cx; bul.y2 = (x * Math.sin(start+sweep)) + arc.cy; sweep = arc.sweep % 360; bul.bulge = sweep; return bul; } //========================================================================================== // bulgeToArc //========================================================================================== function bulgeToArc(bul) { var one,x,y,angle,radius,sdir,edir,mdir,mx,my; var dx,dy,length,arc,atan,bulge,tan; arc = new Object(); arc.cx = 0; arc.cy = 0; arc.radius = 0; arc.start = 0; arc.sweep = 0; arc.rev = false; one = 1; if (bul.bulge < 0) one = -1; bulge = Math.abs(bul.bulge); bulge = bulge / 180 * Math.PI; bulge = bulge / 2; dx = Math.abs(bul.x2 - bul.x1); dy = Math.abs(bul.y2 - bul.y1); length = Math.sqrt(dx*dx + dy*dy); x = length / 2.0; angle = (Math.PI / 2) - bulge; tan = Math.tan(angle); if (isNaN(tan)) tan = 1; y = tan * x * one; arc.radius = Math.sqrt(x*x + y*y) if (arc.radius > 1.0E20) return null; //-------------- Calculate Arc -------------- angle = lineAngle(bul.x1,bul.y1,bul.x2,bul.y2); angle = angle / 180 * Math.PI; arc.cx = (Math.cos(angle) * x - Math.sin(angle) * y) + bul.x1; arc.cy = (Math.sin(angle) * x + Math.cos(angle) * y) + bul.y1; y = y + (arc.radius * (-one)); mx = (Math.cos(angle) * x - Math.sin(angle) * y) + bul.x1; my = (Math.sin(angle) * x + Math.cos(angle) * y) + bul.y1; //--------------------- Arc Angles ------------------------ sdir = lineAngle(arc.cx,arc.cy,bul.x1,bul.y1); cdir = lineAngle(arc.cx,arc.cy,mx,my); edir = lineAngle(arc.cx,arc.cy,bul.x2,bul.y2); sdir = (sdir + 360) % 360; cdir = (cdir + 360) % 360; edir = (edir + 360) % 360; ts = Math.max(sdir,edir); te = Math.min(sdir,edir); tc = cdir; sdir = ts; edir = te; ts = ts - te tc = tc - te // ASSUME ORDERED ts = (ts + 360) % 360; tc = (tc + 360) % 360; if (ts > tc) { arc.rev = true; ts = sdir; sdir = (edir + 360) % 360; edir = ts; } //-------------- Set Arc ------------------ arc.start = sdir; arc.sweep = edir - sdir; if (arc.sweep > 360) arc.sweep = (360 - arc.sweep) % 360; return arc; }