[Sie-developers] 線の太さを計算する式の改良案

Back to archive index

開発者のための、SIE関連 開発者のための、SIE関連
2008年 4月 29日 (火) 17:03:31 JST


revulo です。
stroke-width の処理についての提案です。


現在の SIE では、表示する線の太さを次のような式で計算しています。

  var swx = sw.value * Math.sqrt((w*w*matrix.a*matrix.a +
h*h*matrix.d*matrix.d) / wwhh);

この部分を、

  var swx = sw.value * Math.sqrt(matrix.a * matrix.d - matrix.b * matrix.c);

このように変更したらどうかと思うのですが、いかがでしょうか?


変えたいと思った理由については、以下の SVG ファイルを表示してみて下さい。

<?xml version="1.0"?>
<svg width="350" height="200" xmlns="http://www.w3.org/2000/svg">
  <g transform="translate(50,50)">
    <g fill="none" stroke="green" stroke-width="10">
      <line x1="0" y1="0" x2="100" y2="0" />
      <line x1="0" y1="0" x2="0" y2="100" />
    </g>
  </g>
  <g transform="translate(200,50) rotate(60)">
    <g fill="none" stroke="red" stroke-width="10">
      <line x1="0" y1="0" x2="100" y2="0" />
      <line x1="0" y1="0" x2="0" y2="100" />
    </g>
  </g>
</svg>

現在の計算方法ですと、rotate の変換を施した時に、線の太さが細くなってしまいます。
極端な例としては、90 度回転させた場合には、線の太さがゼロになってしまいます。


そこで提案なのですが、行列式に相当する ad-bc という値を用いてはどうでしょう?
行列式は、その行列の表す変換によって面積が何倍になるか、という値ですので、
sqrt(ad-bc) という値は、線の太さが何倍になるかを示していると考えられます。
この値を用いた場合、

・scale(x) の変換を施した場合は、線の太さも x 倍される
・rotate や skew の変換では、線の太さは変わらない

のように、かなりそれらしい動作になります。
今までの方法と比べると、計算量も少なくて済みます。


皆様のご意見を伺いたく思います。


P.S. Inkscape は、おそらくこれと同じ方法で線の太さを計算していると思います。
     検索をしていて、Inkscape のソースコードの一部らしきものが出てきたのですが、
     その処理内容が、面積比の 1/2 乗を係数として掛ける、というものでしたので、
     それをヒントに書いたのが上記のコードです。




Sie-developers メーリングリストの案内
Back to archive index