Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
  <head>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
  <style>
    rect{
      /*shape-rendering:crispEdges*/
    } 
    path {
      stroke-opacity:1.0; 
      stroke-width:1;
      stroke:black;
    }
    .newpath {
        stroke-width:3;
        stroke:#00FF00;
      stroke-opacity:0.5;
      shape-rendering:crispEdges
      }
    svg {border:1px solid red}
    #containerDiv{
      width:100%;
      height:100%;
      /*overflow:scroll;*/
    }
    #coord{white-space:nowrap}
    body {height:11000px}
  </style>
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
  
</head>  
<meta charset=utf-8 />
<title>Bounding box, various cubic curves</title>
</head>
<body>
  <h2>Bounding box, various cubic curves</h2>
  <div id="coord"></div>
<div id="containerDiv"></div>
</body>
</html>
 
// noprotect
var data1 = ["M352,5779.724c499,2-3-89,496-84",
"M478,2877.472c247,3-255-88,244-83",
"M478,2392.817c247,3-246,14,244-83",
"M478,3361.031c247-69-246,14,244-83",
"M500.5,1403.542c273-45-220,38,199-37",
"M500.5,2587.469c215,96-220,38,199-37",
"M406,1823.559c404,146-31,88,388,13",
"M406,2064.553c86,150-31,88,388,13",
"M406,4966.489c261,149-31,88,388,13",
"M406,4484.496c382,141-31,88,388,13",
"M394.5,6471.436c405,75-8,22,411-53",
"M394.5,5279.895c449-4-8,22,411-53",
"M394.5,6247.762c449-4,0,0,411-53",
"M489.5,3565.342c449-4,0,0,221-8",
"M479.072,3809.049c529-26,0,0,167-6",
"M516.5,1644.744c352-80,0,0,167-6",
"M798.002,4082.546c-529,7-523-141.999-12-38.999",
"M801.469,6774.896c-550.999-16-522.999-142-1-140",
"M799.765,4354.818c-542,32-523-142-1-140",
"M770.439,7017.016c-380.001-148-523.001-142-1-140",
"M769.988,274.009C390.988,266.009,247.988,272.009,769.988,274.009",
"M794.813,1141.56C277.813,1150.56,272.813,1139.56,794.813,1141.56",
"M785.217,901.998C320.216,900.998,263.217,899.998,785.217,901.998",
"M347.5,462.172c505-17-17-18,505-16",
"M339.5,663.235c521,0-1-1,521,1",
"M377.5,5495.454c445,0-77-1,445,1",
"M377.5,5978.951c372,1-77-1,445,1",
"M564.756,3078.079c372,1-77-1-77-1",
"M602.874,4750.803c196.999,91-77-1-77-1",
"M731.169,7500.317c-551-16-74.463,21-1-140",
"M731.169,7209.412c-551-4.777-74.463,6.271-1-41.811",
"M1075.169,7682.533c-1996.043-2.379-269.747,3.121-3.622-20.811",
"M612.657,8228.399c-57.988-464.354,2.249,314.834-1-140",
"M748.791,9246.203c-48.561-445.45,0,0,0-246.418",
"M407.051,9488.014c8.771-403.029,0,0,0-246.416",
"M492,7954.201c258.471-128.029-126-68.002,216-56",
"M529.006,8937.162c232.271-130.145,105.271-167.076,123.23-0.48",
"M532.461,8453.83c213.563-131.8,105.271-167.076,123.232-0.479",
"M538.385,8695.068c169.485-128.53,105.27-167.075,123.23-0.479",
"M177.365,9657.754 C2314.484,9433.758-164.635,9645.75,177.365,9657.754",
"M177.365,9863.064 C2314.484,9798.949-164.635,9859.629,177.365,9863.064",
"M177.365,10098.412 C2314.482,10062.607-164.635,10096.492,177.365,10098.412",
"M121.108,10352.402c2137.118-35.807,82,41-10.136-40.705",
"M163.396,10885.141 C453.589,10902.539,162.471,10562.539,163.396,10885.141",
"M228.071,10627.99 C1915.305,10622.137,202.129,10387.359,228.071,10627.99",
"M152.222,10991.809 C1084.453,10959.602,1582.453,10868.578,152.222,10991.809"];
(function(){
  // ------------------------------------------------
  var pow = Math.pow,
  sqrt = Math.sqrt,
  min = Math.min,
  max = Math.max;
abs = Math.abs;
  
function getBoundsOfCurve (x0, y0, x1, y1, x2, y2, x3, y3)
  {
    var tvalues = new Array();
    var bounds = [new Array(), new Array()];
    var points = new Array();
    var a,b,c,t,t1,t2,b2ac,sqrtb2ac;
    for (var i = 0; i < 2; ++i)
    {
      if (i==0)
      {
        b = 6 * x0 - 12 * x1 + 6 * x2;
        a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
        c = 3 * x1 - 3 * x0;
      }
      else
      {
        b = 6 * y0 - 12 * y1 + 6 * y2;
        a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
        c = 3 * y1 - 3 * y0;
      }
      
      if (abs(a) < 1e-12) // Numerical robustness
      {
        if (abs(b) < 1e-12) // Numerical robustness
        {
          continue;
        }
        t = -c / b;
        if (0 < t && t < 1)
        {
          tvalues.push(t);
        }
        continue;
      }
      b2ac = b*b - 4 * c * a;
      sqrtb2ac = sqrt(b2ac);
      if (b2ac < 0)
      {
        continue;
      }
      t1 = (-b + sqrtb2ac) / (2 * a);
      if (0 < t1 && t1 < 1)
      {
        tvalues.push(t1);
      }
      t2 = (-b - sqrtb2ac) / (2 * a);
      if (0 < t2 && t2 < 1)
      {
        tvalues.push(t2);
      }
    }
    
    var x, y, j = tvalues.length, jlen = j, mt;
    while(j--)
    {
      t = tvalues[j];
      mt = 1-t;
      x = (mt*mt*mt*x0) + (3*mt*mt*t*x1) + (3*mt*t*t*x2) + (t*t*t*x3);
      bounds[0][j] = x;
      y = (mt*mt*mt*y0) + (3*mt*mt*t*y1) + (3*mt*t*t*y2) + (t*t*t*y3);
      bounds[1][j] = y;
      points[j] = {X: x, Y: y};
    }
    tvalues[jlen] = 0;
    tvalues[jlen+1] = 1;
    points[jlen] = {X: x0, Y:y0};
    points[jlen+1] = {X: x3, Y:y3};
    bounds[0][jlen] = x0;
    bounds[1][jlen] = y0;
    bounds[0][jlen+1] = x3;
    bounds[1][jlen+1] = y3;
    tvalues.length = bounds[0].length = bounds[1].length = points.length = jlen+2;
    
    return {
      left: min.apply(null, bounds[0]),
      top: min.apply(null, bounds[1]),
      right: max.apply(null, bounds[0]),
      bottom: max.apply(null, bounds[1]),
      points: points, // local extremes
      tvalues: tvalues // t values of local extremes
    };
  };
    
  function getBoundsOfPath (path)
  {
    //var curve = path2curve(path);
    curve = path;
    ////console.log(JSON.stringify(path));
    ////console.log("--------------------------------------------------------------------");
    //console.log(JSON.stringify(curve));
    var bounds, s, startX, startY,
        minx = Number.MAX_VALUE,
        miny = Number.MAX_VALUE,
        maxx = Number.MIN_VALUE,
        maxy = Number.MIN_VALUE;
var isC = false;
    for (var i = 0, ilen = curve.length; i < ilen; i++)
    {
      //var val = 6;
      //if(i!=val && i!=val-1) continue;
      var s = curve[i];
      ////console.log(s);
      
      if (s[0] == 'M')
      {
        if (typeof(curve[i+1]) != "undefined" && curve[i+1][0] == "C")
        {
        startX = s[1];
        startY = s[2];
        if (startX < minx) minx = startX;
        if (startX > maxx) maxx = startX;
        if (startY < miny) miny = startY;
        if (startY > maxy) maxy = startY;
        }
      }
      else 
      
      if (s[0] == 'C')
      {
        isC = true;
        //if(i==val)
        //{
        bounds = getBoundsOfCurve(startX, startY, s[1], s[2], s[3], s[4], s[5], s[6]);
        //bounds = calculate_standard_bbox(startX, startY, s[1], s[2], s[3], s[4], s[5], s[6]);
  //bounds = cubic_extrema_external(startX, startY, s[1], s[2], s[3], s[4], s[5], s[6]);
        
        ////console.log(JSON.stringify(bounds));
        if (bounds.left < minx) minx = bounds.left;
        if (bounds.right > maxx) maxx = bounds.right;
        if (bounds.top < miny) miny = bounds.top;
        if (bounds.bottom > maxy) maxy = bounds.bottom;
        startX = s[5];
        startY = s[6];
      }
      ////console.log(JSON.stringify(bounds));
      //if(s[0] == 'C')
      //{
      //  currentX = s[5], currentY = s[6];
      //}
    }
//    left: this.left + (minX + deltaX / 2),
  //          top: this.top + (minY + deltaY / 2),
    
    if (!isC) minx = maxx = miny = maxy = 0;
    
    var boundsFinal = {
      left: minx,
      top: miny,
      width: maxx - minx,
      height: maxy - miny
    };
    ////console.log(JSON.stringify(boundsFinal));
    return boundsFinal;
  }
  window.getBoundsOfPath = getBoundsOfPath;
  window.getBoundsOfCurve = getBoundsOfCurve;
})();
// DRAW SECTION
function original_data_arr_to_path (arr)
{
  // M366,75C59,40,59,40,366,75
  var str="M"+arr[0]+","+arr[1];
  str+="C"+arr[2]+",";
  str+=arr[3]+",";
  str+=arr[4]+",";
  str+=arr[5]+",";
  str+=arr[6]+",";
  str+=arr[7]+",";
   return str;
}
function newdata_arr_to_path (arr)
{
  var str="";
  for(var i=0,m=arr.length;i<m;i++)
  {
    str+=i?"L":"M";
    str+=arr[i].X+","+arr[i].Y;
  }
  return str;
}
var w = 1200, h=11200;
var R = Raphael("containerDiv",w,h);
R.canvas.setAttribute("id", "p");
//Raphael.parsePathString("M193,169C200,5,200,210,26,74Z");
var d;
var b; // bounds
var p; // path
for(i=0;i<data1.length;i++)
{
  d = data1[i];
  d = Raphael.parsePathString(d);
  d = Raphael._pathToAbsolute(d);
  p = d;
  b = getBoundsOfCurve(
    p[0][1], 
    p[0][2],
    p[1][1],
    p[1][2],
    p[1][3],
    p[1][4],
    p[1][5],
    p[1][6]);
  R.rect(b.left,b.top,b.right-b.left,b.bottom-b.top).attr("stroke", "red").attr("fill","red").attr("stroke-opacity",0.5).attr("fill-opacity",0.1);
  R.path(d);
  
  for(j=0;j<b.points.length;j++)
  {
  R.circle(b.points[j].X,b.points[j].Y, 5).attr("stroke", "red").attr("fill","red").attr("stroke-opacity",0.5).attr("fill-opacity",0.1);
  }
}
  
Output 300px

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers