開発者のための、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 乗を係数として掛ける、というものでしたので、 それをヒントに書いたのが上記のコードです。