←Previous | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Next→
  _display: defaultDisplay,
  _fill: defaultFill,
  _fontFamily: defaultFontFamily,
  _fontSize: defaultFontSize,
  _fontStyle: defaultFontStyle,
  _fontWeight: defaultFontWeight,
  _opacity: defaultOpacity,
  _stroke: defaultStroke,
  _strokeLinecap: defaultStrokeLinecap,
  _strokeLinejoin: defaultStrokeLinejoin,
  _strokeWidth: defaultStrokeWidth,
  _textAnchor: defaultTextAnchor
  });
}

//popDefault ()
function popDefault () {
  let t = defaultStack.pop ();  //Object
  defaultAlignmentBaseline = t._alignmentBaseline;
  defaultDisplay = t._display;
  defaultFill = t._fill;
  defaultFontFamily = t._fontFamily;
  defaultFontSize = t._fontSize;
  defaultFontStyle = t._fontStyle;
  defaultFontWeight = t._fontWeight;
  defaultOpacity = t._opacity;
  defaultStroke = t._stroke;
  defaultStrokeLinecap = t._strokeLinecap;
  defaultStrokeLinejoin = t._strokeLinejoin;
  defaultStrokeWidth = t._strokeWidth;
  defaultTextAnchor = t._textAnchor;
}

//setDefaultAlignmentBaseline (alignmentBaseline)
//  String alignmentBaseline
function setDefaultAlignmentBaseline (alignmentBaseline) {
  defaultAlignmentBaseline = alignmentBaseline;
}

//setDefaultDisplay (display)
//  String display
function setDefaultDisplay (display) {
  defaultDisplay = display;
}

//setDefaultFill (fill)
//  String fill
function setDefaultFill (fill) {
  defaultFill = fill;
}

//setDefaultFontFamily (fontFamily)
//  String fontFamily
function setDefaultFontFamily (fontFamily) {
  defaultFontFamily = fontFamily;
}

//setDefaultFontSize (fontSize)
//  double fontSize
function setDefaultFontSize (fontSize) {
  defaultFontSize = fontSize;
}

//setDefaultFontStyle (fontStyle)
//  String fontStyle
function setDefaultFontStyle (fontStyle) {
  defaultFontStyle = fontStyle;
}

//setDefaultFontWeight (fontWeight)
//  String fontWeight
function setDefaultFontWeight (fontWeight) {
  defaultFontWeight = fontWeight;
}

//setDefaultOpacity (opacity)
//  double opacity
function setDefaultOpacity (opacity) {
  defaultOpacity = opacity;
}

//setDefaultStroke (stroke)
//  String stroke
function setDefaultStroke (stroke) {
  defaultStroke = stroke;
}

//setDefaultStrokeLinecap (strokeLinecap)
//  String strokeLinecap
function setDefaultStrokeLinecap (strokeLinecap) {
  defaultStrokeLinecap = strokeLinecap;
}

//setDefaultStrokeLinejoin (strokeLinejoin)
//  String strokeLinejoin
function setDefaultStrokeLinejoin (strokeLinejoin) {
  defaultStrokeLinejoin = strokeLinejoin;
}

//setDefaultStrokeWidth (strokeWidth)
//  double strokeWidth
function setDefaultStrokeWidth (strokeWidth) {
  defaultStrokeWidth = strokeWidth;
}

//setDefaultTextAnchor (textAnchor)
//  String textAnchor
function setDefaultTextAnchor (textAnchor) {
  defaultTextAnchor = textAnchor;
}

//--------------------------------------------------------------------------------
//common

//o = setAlignmentBaseline (o, alignmentBaseline)
//  Object o
//  String alignmentBaseline
function setAlignmentBaseline (o, alignmentBaseline) {
  if (alignmentBaseline !== null) {
    nsSetAttr (o, null, "alignment-baseline", alignmentBaseline);
  }
  return o;
}

//o = setDisplay (o, display)
//  Object o
//  String display
function setDisplay (o, display) {
  if (display !== null) {
    nsSetAttr (o, null, "display", display);
  }
  return o;
}

//o = setFill (o, fill)
//  Object o
//  String fill
function setFill (o, fill) {
  if (fill !== null) {
    nsSetAttr (o, null, "fill", fill);
  }
  return o;
}

//o = setFontFamily (o, fontFamily)
//  Object o
//  String fontFamily
function setFontFamily (o, fontFamily) {
  if (fontFamily !== null) {
    nsSetAttr (o, null, "font-family", fontFamily);
  }
  return o;
}

//o = setFontSize (o, fontSize)
//  Object o
//  double fontSize
function setFontSize (o, fontSize) {
  if (!isNaN (fontSize)) {
    nsSetAttr (o, null, "font-size", fontSize);
  }
  return o;
}

//o = setFontStyle (o, fontStyle)
//  Object o
//  String fontStyle
function setFontStyle (o, fontStyle) {
  if (fontStyle !== null) {
    nsSetAttr (o, null, "font-style", fontStyle);
  }
  return o;
}

//o = setFontWeight (o, fontWeight)
//  Object o
//  String fontWeight
function setFontWeight (o, fontWeight) {
  if (fontWeight !== null) {
    nsSetAttr (o, null, "font-weight", fontWeight);
  }
  return o;
}

//o = setOpacity (o, opacity)
//  Object o
//  double opacity
function setOpacity (o, opacity) {
  if (!isNaN (opacity)) {
    nsSetAttr (o, null, "opacity", opacity);
  }
  return o;
}

//o = setStroke (o, stroke)
//  Object o
//  String stroke
function setStroke (o, stroke) {
  if (stroke !== null) {
    nsSetAttr (o, null, "stroke", stroke);
  }
  return o;
}

//o = setStrokeLinecap (o, strokeLinecap)
//  Object o
//  String strokeLinecap
function setStrokeLinecap (o, strokeLinecap) {
  if (strokeLinecap !== null) {
    nsSetAttr (o, null, "stroke-linecap", strokeLinecap);
  }
  return o;
}

//o = setStrokeLinejoin (o, strokeLinejoin)
//  Object o
//  String strokeLinejoin
function setStrokeLinejoin (o, strokeLinejoin) {
  if (strokeLinejoin !== null) {
    nsSetAttr (o, null, "stroke-linejoin", strokeLinejoin);
  }
  return o;
}

//o = setStrokeWidth (o, strokeWidth)
//  Object o
//  double strokeWidth
function setStrokeWidth (o, strokeWidth) {
  if (!isNaN (strokeWidth)) {
    nsSetAttr (o, null, "stroke-width", strokeWidth);
  }
  return o;
}

//o = setTextAnchor (o, textAnchor)
//  Object o
//  String textAnchor
function setTextAnchor (o, textAnchor) {
  if (textAnchor !== null) {
    nsSetAttr (o, null, "text-anchor", textAnchor);
  }
  return o;
}

//--------------------------------------------------------------------------------
//arc

//o = createArc (cx, cy, rx, ry, ta, tb, tc, closed)
//  Object o
//  double cx  中心
//  double cy
//  double rx  半径
//  double ry
//  double ta  開始角
//  double tb  終了角
//  double tc  回転角
//  boolean closed  true=扇形にする(中心と開始位置および中心と終了位置を直線で結ぶ)
function createArc (cx, cy, rx, ry, ta, tb, tc, closed) {
  return (
    setStrokeWidth (
      setStroke (
        setFill (
          moveArc (nsCreateNode (SVGNS, "path"), cx, cy, rx, ry, ta, tb, tc, closed),
          defaultFill),
        defaultStroke),
      defaultStrokeWidth)
    );
}

//o = moveArc (o, cx, cy, rx, ry, ta, tb, tc, closed)
//  Object o
//  double cx
//  double cy
//  double rx
//  double ry
//  double ta
//  double tb
//  double tc
//  boolean closed
function moveArc (o, cx, cy, rx, ry, ta, tb, tc, closed) {
  //ta<=tb<=ta+2*piにする
  if (tb < ta) {
    let t = ta;  //double
    ta = tb;
    tb = t;
  }
  tb = min2 (tb - ta, TWOPI) + ta;
  //開始位置と終了位置
  let xa = cos (ta) * rx;  //double
  let ya = sin (ta) * ry;  //double
  let xb = cos (tb) * rx;  //double
  let yb = sin (tb) * ry;  //double
  //回転
  if (tc) {
    let c = cos (tc);  //double
    let s = sin (tc);  //double
    let t;  //double
    t  = c * xa - s * ya;
    ya = s * xa + c * ya;
    xa = t;
    t  = c * xb - s * yb;
    yb = s * xb + c * yb;
    xb = t;
  }
  let a = ["M",cx + xa, cy + ya,
           "A", rx, ry, deg (tc), tb - ta <= PI ? 0 : 1, 1, cx + xb, cy + yb];  //Array
  //扇形にする(中心と開始位置および中心と終了位置を直線で結ぶ)
  if (closed) {
    a.push ("L", cx, cy, "Z");
  }
  return nsSetAttr (o, null, "d", a.join (" "));
}

//--------------------------------------------------------------------------------
//circle

//o = createCircle (cx, cy, r)
//  Object o
//  double cx
//  double cy
//  double r
function createCircle (cx, cy, r) {
  return (
    setStrokeWidth (
      setStroke (
        setFill (
          moveCircle (nsCreateNode (SVGNS, "circle"), cx, cy, r),
          defaultFill),
        defaultStroke),
      defaultStrokeWidth)
    );
}

//o = moveCircle (o, cx, cy, r)
//  Object o
//  double cx
//  double cy
//  double r
function moveCircle (o, cx, cy, r) {
  return nsSetAttr (o, null, "cx", cx, "cy", cy, "r", r);
}

//--------------------------------------------------------------------------------
//defs

//o = createDefs ()
//  Object o
function createDefs () {
  return nsCreateNode (SVGNS, "defs");
}

//--------------------------------------------------------------------------------
//ellipse

//o = createEllipse (cx, cy, rx, ry)
//  Object o
//  double cx
//  double cy
//  double rx
//  double ry
function createEllipse (cx, cy, rx, ry) {
  return (
    setStrokeWidth (
      setStroke (
        setFill (
          moveCircle (nsCreateNode (SVGNS, "ellipse"), cx, cy, rx, ry),
          defaultFill),
        defaultStroke),
      defaultStrokeWidth)
    );
}

//o = moveEllipse (o, cx, cy, rx, ry)
//  Object o
//  double cx
//  double cy
//  double rx
//  double ry
function moveEllipse (o, cx, cy, rx, ry) {
  return nsSetAttr (o, null, "cx", cx, "cy", cy, "rx", rx, "ry", ry);
}

//--------------------------------------------------------------------------------
//g

//o = createG ()
//  Object o
function createG () {
  return nsCreateNode (SVGNS, "g");
}

//--------------------------------------------------------------------------------
//line

//o = createLine (x1, y1, x2, y2)
//  Object o
//  double x1
//  double y1
//  double x2
//  double y2
function createLine (x1, y1, x2, y2) {
  return (
    setStrokeWidth (
      setStrokeLinejoin (
        setStrokeLinecap (
          setStroke (
            moveLine (nsCreateNode (SVGNS, "line"), x1, y1, x2, y2),
            defaultStroke),
          defaultStrokeLinecap),
        defaultStrokeLinejoin),
      defaultStrokeWidth)
    );
}

//o = moveLine (o, x1, y1, x2, y2)
//  Object o
//  double x1
//  double y1
//  double x2
//  double y2
function moveLine (o, x1, y1, x2, y2) {
  return nsSetAttr (o, null, "x1", x1, "y1", y1, "x2", x2, "y2", y2);
}

//--------------------------------------------------------------------------------
//path
//
//  移動
//    M x y
//    m dx dy
//  水平線
//    H x
//    h dx
//  垂直線
//    V y
//    v dy
//  直線
//    L x y
//    l dx dy
//  2次ベジェ曲線
//    Q x1 y1 x y
//    q dx1 dy1 dx dy
//    T x y
//    t dx dy
//  3次ベジェ曲線
//    C x1 y1 x2 y2 x y
//    c dx1 dy1 dx2 dy2 dx dy
//    S x2 y2 x y
//    s dx2 dy2 dx dy
//  円弧
//    A rx ry x-axis-rotation large-arc-flag sweep-flag x y
//    a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
//  閉路
//    Z
//    z
//

//o = createPath (d)
//  Object o
//  String d
function createPath (d) {
  return (
    setStrokeWidth (
      setStrokeLinejoin (
        setStrokeLinecap (
          setStroke (
            setFill (
              movePath (nsCreateNode (SVGNS, "path"), d),
              defaultFill),
            defaultStroke),
          defaultStrokeLinecap),
        defaultStrokeLinejoin),
      defaultStrokeWidth)
    );
}

//o = movePath (o, d)
//  Object o
//  String d
function movePath (o, d) {
  return nsSetAttr (o, null, "d", d);
}

//--------------------------------------------------------------------------------
//polygon

//o = createPolygon (points)
//  Object o
//  String points
function createPolygon (points) {
  return (
    setStrokeWidth (
      setStroke (
        setFill (
          movePolygon (nsCreateNode (SVGNS, "polygon"), points),
          defaultFill),
        defaultStroke),
      defaultStrokeWidth)
    );
}

//o = movePolygon (o, points)
//  Object o
//  String points
function movePolygon (o, points) {
  return nsSetAttr (o, null, "points", points);
}

//--------------------------------------------------------------------------------
//polyline

//o = createPolyline (points)
//  Object o
//  String points
function createPolyline (points) {
  return (
    setStrokeWidth (
      setStrokeLinejoin (
        setStrokeLinecap (
          setStroke (
            movePolyline (nsCreateNode (SVGNS, "polyline"), points),
            defaultStroke),
          defaultStrokeLinecap),
        defaultStrokeLinejoin),
      defaultStrokeWidth)
    );
}

//o = movePolyline (o, points)
//  Object o
//  String points
function movePolyline (o, points) {
  return nsSetAttr (o, null, "points", points);
}

//--------------------------------------------------------------------------------
//radialGradient
//
//  機能
//    同心円グラデーションを作る
//    グラデーションは複数のオブジェクトで使用できる
//  文法
//    defsElement = createRadialGradient ([offset0, color0, ...])
//  引数
//    offsetN  数値    中心からの割合(0~1)
//    colorN   文字列  offsetNの位置の色
//  準備
//    defsElement = createDefs ();
//    appendNode (svgElement, defsElement);
//  作成
//    gradientElement = createRadialGradient (elementId, [0, "black", 1, "white"]);
//    appendNode (defsElement, gradientElement);
//    setFill (circleElement, "url(#" + elementId + ")");
//

//o = createRadialGradient (elementId, a)
//  Object o
//  String elementId
//  Array a
function createRadialGradient (elementId, a) {
  let gradientElement = nsSetAttr (nsCreateNode (SVGNS, "radialGradient"), null,  //Gは大文字
                                   "id", elementId);  //Object
  for (let i = 0, l = a.length; i < l; i += 2) {  //int
    appendNode (gradientElement,
                nsSetAttr (nsCreateNode (SVGNS, "stop"), null,
                           "offset", a[i],
                           "stop-color", a[i + 1]));
  }
  return gradientElement;
}

//--------------------------------------------------------------------------------
//rect

//o = createRect (x, y, width, height)
//  Object o
//  double x
//  double y
//  double width
//  double height
function createRect (x, y, width, height) {
  return (
    setStrokeWidth (
      setStroke (
        setFill (
          moveRect (nsCreateNode (SVGNS, "rect"), x, y, width, height),
          defaultFill),
        defaultStroke),
      defaultStrokeWidth)
    );
}

//o = createRoundRect (x, y, width, height, rx, ry)
//  Object o
//  double x
//  double y
//  double width
//  double height
//  double rx
//  double ry
function createRoundRect (x, y, width, height, rx, ry) {
  return (
    setStrokeWidth (
      setStroke (
        setFill (
          moveRoundRect (nsCreateNode (SVGNS, "rect"), x, y, width, height, rx, ry),
          defaultFill),
        defaultStroke),
      defaultStrokeWidth)
    );
}

//o = moveRect (o, x, y, width, height)
//  Object o
//  double x
//  double y
//  double width
//  double height
function moveRect (o, x, y, width, height) {
  return nsSetAttr (o, null, "x", x, "y", y, "width", width, "height", height);
}

//o = moveRoundRect (o, x, y, width, height, rx, ry)
//  Object o
//  double x
//  double y
//  double width
//  double height
//  double rx
//  double ry
function moveRoundRect (o, x, y, width, height, rx, ry) {
  return nsSetAttr (o, null, "x", x, "y", y, "width", width, "height", height, "rx", rx, "ry", ry);
}

//--------------------------------------------------------------------------------
//text

//o = createText (x, y, text)
//  Object o
//  double x
//  double y
//  String text
function createText (x, y, text) {
  return (
    setFontWeight (
      setFontStyle (
        setFontSize (
          setFontFamily (
            setFill (
              setAlignmentBaseline (
                appendNode (moveText (nsCreateNode (SVGNS, "text"), x, y), text),
                defaultAlignmentBaseline),
              defaultFill),
            defaultFontFamily),
          defaultFontSize),
        defaultFontStyle),
      defaultFontWeight)
    );
}

//o = moveText (o, x, y)
//  Object o
//  double x
//  double y
function moveText (o, x, y) {
  return nsSetAttr (o, null, "x", x, "y", y);
}

//o = setText (o, text)
//  Object o
//  String text
function setText (o, text) {
  o.firstChild.nodeValue = text;
  return o;
}

//--------------------------------------------------------------------------------
const COLOR_NAMES = {
  aliceblue: "#F0F8FF",
  antiquewhite: "#FAEBD7",
  aqua: "#00FFFF",
  aquamarine: "#7FFFD4",
  azure: "#F0FFFF",
  beige: "#F5F5DC",
  bisque: "#FFE4C4",
  black: "#000000",
  blanchedalmond: "#FFEBCD",
  blue: "#0000FF",
  blueviolet: "#8A2BE2",
  brown: "#A52A2A",
  burlywood: "#DEB887",
  cadetblue: "#5F9EA0",
  chartreuse: "#7FFF00",
  chocolate: "#D2691E",
  coral: "#FF7F50",
  cornflowerblue: "#6495ED",
  cornsilk: "#FFF8DC",
  crimson: "#DC143C",
  cyan: "#00FFFF",
  darkblue: "#00008B",
  darkcyan: "#008B8B",
  darkgoldenrod: "#B8860B",
  darkgray: "#A9A9A9",
  darkgreen: "#006400",
  darkkhaki: "#BDB76B",
  darkmagenta: "#8B008B",
  darkolivegreen: "#556B2F",
  darkorange: "#FF8C00",
  darkorchid: "#9932CC",
  darkred: "#8B0000",
  darksalmon: "#E9967A",
  darkseagreen: "#8FBC8F",
  darkslateblue: "#483D8B",
  darkslategray: "#2F4F4F",
  darkturquoise: "#00CED1",
  darkviolet: "#9400D3",
  deeppink: "#FF1493",
  deepskyblue: "#00BFFF",
  dimgray: "#696969",
  dodgerblue: "#1E90FF",
  firebrick: "#B22222",
  floralwhite: "#FFFAF0",
  forestgreen: "#228B22",
  fuchsia: "#FF00FF",
  gainsboro: "#DCDCDC",
  ghostwhite: "#F8F8FF",
  gold: "#FFD700",
  goldenrod: "#DAA520",
  gray: "#808080",
  green: "#008000",
  greenyellow: "#ADFF2F",
  honeydew: "#F0FFF0",
  hotpink: "#FF69B4",
  indianred: "#CD5C5C",
  indigo: "#4B0082",
  ivory: "#FFFFF0",
  khaki: "#F0E68C",
  lavender: "#E6E6FA",
  lavenderblush: "#FFF0F5",
  lawngreen: "#7CFC00",
  lemonchiffon: "#FFFACD",
  lightblue: "#ADD8E6",
  lightcoral: "#F08080",
  lightcyan: "#E0FFFF",
  lightgoldenrodyellow: "#FAFAD2",
  lightgreen: "#90EE90",
  lightgrey: "#D3D3D3",
  lightpink: "#FFB6C1",
  lightsalmon: "#FFA07A",
  lightseagreen: "#20B2AA",
  lightskyblue: "#87CEFA",
  lightslategray: "#778899",
  lightsteelblue: "#B0C4DE",
  lightyellow: "#FFFFE0",
  lime: "#00FF00",
  limegreen: "#32CD32",
  linen: "#FAF0E6",
  magenta: "#FF00FF",
  maroon: "#800000",
  mediumaquamarine: "#66CDAA",
  mediumblue: "#0000CD",
  mediumorchid: "#BA55D3",
  mediumpurple: "#9370DB",
  mediumseagreen: "#3CB371",
  mediumslateblue: "#7B68EE",
  mediumspringgreen: "#00FA9A",
  mediumturquoise: "#48D1CC",
  mediumvioletred: "#C71585",
  midnightblue: "#191970",
  mintcream: "#F5FFFA",
  mistyrose: "#FFE4E1",
  moccasin: "#FFE4B5",
  navajowhite: "#FFDEAD",
  navy: "#000080",
  oldlace: "#FDF5E6",
  olive: "#808000",
  olivedrab: "#6B8E23",
  orange: "#FFA500",
  orangered: "#FF4500",
  orchid: "#DA70D6",
  palegoldenrod: "#EEE8AA",
  palegreen: "#98FB98",
  paleturquoise: "#AFEEEE",
  palevioletred: "#DB7093",
  papayawhip: "#FFEFD5",
  peachpuff: "#FFDAB9",
  peru: "#CD853F",
  pink: "#FFC0CB",
  plum: "#DDA0DD",
  powderblue: "#B0E0E6",
  purple: "#800080",
  red: "#FF0000",
  rosybrown: "#BC8F8F",
  royalblue: "#4169E1",
  saddlebrown: "#8B4513",
  salmon: "#FA8072",
  sandybrown: "#F4A460",
  seagreen: "#2E8B57",
  seashell: "#FFF5EE",
  sienna: "#A0522D",
  silver: "#C0C0C0",
  skyblue: "#87CEEB",
  slateblue: "#6A5ACD",
  slategray: "#708090",
  snow: "#FFFAFA",
  springgreen: "#00FF7F",
  steelblue: "#4682B4",
  tan: "#D2B48C",
  teal: "#008080",
  thistle: "#D8BFD8",
  tomato: "#FF6347",
  turquoise: "#40E0D0",
  violet: "#EE82EE",
  wheat: "#F5DEB3",
  white: "#FFFFFF",
  whitesmoke: "#F5F5F5",
  yellow: "#FFFF00",
  yellowgreen: "#9ACD32"
  };

//color = RGBtoColor (rgb)
//  String color
//  Array rgb
//  rgbは[r,g,b]または[r,g,b,a]
//  r,g,b,aは0~1の数値
function RGBtoColor (rgb) {
  let r = max2 (0, min2 (255, floor (rgb[0] * 255 + 0.5)));
  let g = max2 (0, min2 (255, floor (rgb[1] * 255 + 0.5)));
  let b = max2 (0, min2 (255, floor (rgb[2] * 255 + 0.5)));
  let a = rgb.length == 3 ? 1 : max2 (0, min2 (1, rgb[3]));
  return (a == 1 ?
          "rgb(" + r + "," + g + "," + b + ")" :
          "rgba(" + r + "," + g + "," + b + "," + a + ")");
}

//rgb = colorToRGB (color)
//  Array rgb
//  String color
//  rgbは[r,g,b]または[r,g,b,a]
//  r,g,b,aは0~1の数値
function colorToRGB (color) {
  if (COLOR_NAMES[color]) {
    color = COLOR_NAMES[color];
  }
  if (color[0] == "#") {
    if (color.length == 3) {
      let t = parseInt (color.substring (1, 4), 16);
      return [(t >> 8) / 15, (t >> 4 & 15) / 15, (t & 15) / 15];
    } else if (color.length == 7) {
      let t = parseInt (color.substring (1, 7), 16);
      return [(t >> 16) / 255, (t >> 8 & 255) / 255, (t & 255) / 255];
    }
  } else if (color.substring (4) == "rgb(") {
    let i = 4;
    let j = color.indexOf (",", i);
    if (i <= j) {
      let r = max2 (0, min2 (1, parseInt (color.substring (i, j), 10) / 255));
      i = j + 1;
      j = color.indexOf (",", i);
      if (i <= j) {
        let g = max2 (0, min2 (1, parseInt (color.substring (i, j), 10) / 255));
        i = j + 1;
        j = color.indexOf (")", i);
        if (i <= j) {
          let b = max2 (0, min2 (1, parseInt (color.substring (i, j), 10) / 255));
          return [r, g, b];
        }
      }
    }
  } else if (color.substring (5) == "rgba(") {
    let i = 5;
    let j = color.indexOf (",", i);
    if (i <= j) {
      let r = max2 (0, min2 (1, parseInt (color.substring (i, j), 10) / 255));
      i = j + 1;
      j = color.indexOf (",", i);
      if (i <= j) {
        let g = max2 (0, min2 (1, parseInt (color.substring (i, j), 10) / 255));
        i = j + 1;
        j = color.indexOf (",", i);
        if (i <= j) {
          let b = max2 (0, min2 (1, parseInt (color.substring (i, j), 10) / 255));
          i = j + 1;
          j = color.indexOf (")", i);
          if (i <= j) {
            let a = max2 (0, min2 (1, parseFloat (color.substring (i, j))));
            return a == 1 ? [r, g, b] : [r, g, b, a];
          }
        }
      }
    }
  }
  return [0, 0, 0];
}





//========================================================================================
//
//  Vector
//
//========================================================================================



//========================================================================
//平面ベクトル(v~)
//
//    [x]   [v[0]]
//    [y] = [v[1]]
//    [1]   [  1 ]
//

//------------------------------------------------------------------------
//angle なす角
//  acos((a.b)/(|a|*|b|))
//  ゼロベクトルは不可

//t = vAngle (a, b)
//  double t
//  Array a
//  Array b
function vAngle (a, b) {
  let ax = a[0], ay = a[1];  //double
  let bx = b[0], by = b[1];  //double
  return acos ((ax * bx + ay * by) / (hypot2 (ax, ay) * hypot2 (bx, by)));
}

//------------------------------------------------------------------------
//angle a 三角形abcの角a
//  辺abと辺acのなす角

//t = vAngleA (a, b, c)
//  double t
//  Array a
//  Array b
//  Array c
function vAngleA (a, b, c) {
  let ax = a[0], ay = a[1];  //double
  let bx = b[0], by = b[1];  //double
  let cx = c[0], cy = c[1];  //double
  bx -= ax;
  by -= ay;
  cx -= ax;
  cy -= ay;
  return acos ((bx * cx + by * cy) / (hypot2 (bx, by) * hypot2 (cx, cy)));
}

//------------------------------------------------------------------------
//areaoftriangle 三角形の面積
//  三角形abcの面積
//  平面
//    s=1/2*abs((bx-ax)*(cy-ay)-(cx-ax)*(by-ay))
//  空間
//    s=1/2*sqrt(abs(b-a)^2*abs(c-a)^2-((b-a).(c-a))^2)
function vAreaOfTriangle (a, b, c) {
  let ax = a[0], ay = a[1];
  let bx = b[0], by = b[1];
  let cx = c[0], cy = c[1];
  bx -= ax;
  by -= ay;
  cx -= ax;
  cy -= ay;
  return 0.5 * abs (bx * cy - cx * by);
}

//------------------------------------------------------------------------
//azimuth 方位角

//t = vAzimuth (a)
//  double t
//  Array a
function vAzimuth (a) {
  return atan2 (a[1], a[0]);
}

//------------------------------------------------------------------------
//bisect 2分割(中点)
//  (a+b)/2

//a = vBisect (a, b)
//  Array a
//  Array b
function vBisect (a, b) {
  a[0] = (a[0] + b[0]) * 0.5;
  a[1] = (a[1] + b[1]) * 0.5;
  return a;
}

//o = vLetBisect (o, a, b)
//  Array o
//  Array a
//  Array b
function vLetBisect (o, a, b) {
  o[0] = (a[0] + b[0]) * 0.5;
  o[1] = (a[1] + b[1]) * 0.5;
  return o;
}
←Previous | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Next→