質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SVG

SVGは、XMLを基盤とした2Dベクター画像記述言語。画像を線・面といった図形の集合体として扱うベクター画像のため、環境に適した表示が可能です。アニメーション機能もサポートされており、簡単なインタラクティブコンテンツ作成もできます。

Q&A

解決済

1回答

1550閲覧

SVGで双曲線を書きたい

suzunox

総合スコア80

SVG

SVGは、XMLを基盤とした2Dベクター画像記述言語。画像を線・面といった図形の集合体として扱うベクター画像のため、環境に適した表示が可能です。アニメーション機能もサポートされており、簡単なインタラクティブコンテンツ作成もできます。

0グッド

1クリップ

投稿2019/08/31 22:57

###実現したいこと
svgで双曲線を書きたいです。しかし、双曲線はそもそも関数ではないので無理かなと思い始めています。わらにすがるような思いで質問します。
##やってみたこと
放物線は2次関数なのでベジェ曲線で定義可能です。両端の接線を導関数で導き、その交点を制御点として設定すれば、簡単に作成可能です。
しかし双曲線となると円の方程式に近いようなもので関数ではないので、今までのやり方だとどうしても放物線のような曲線になってしまいます。
今までのやりかたで作ったsvgがこちらです。webで表示してみてください。

svg

1<svg height="200" viewBox="0 0 100 100" width="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 2 <marker viewBox="-10 -5 10 10" markerWidth="5" markerHeight="5" id="mk" refX="0" refY="0" orient="auto"> 3 <polyline points="-10,3 0,0 -10,-3" stroke="gray" fill="none" stroke-width="2"></polyline> 4 </marker> 5 <line x1="2" y1="50" x2="98" y2="50" stroke="gray" marker-end="url(#mk)"></line><!--x軸--> 6 <line x1="50" y1="98" x2="50" y2="2" stroke="gray" marker-end="url(#mk)"></line><!--y軸--> 7 <line x1="5" y1="15" x2="95" y2="85" stroke="gray"></line><!--漸近線--> 8 <line x1="5" y1="85" x2="95" y2="15" stroke="gray"></line><!--漸近線--> 9 <path d="M 95,22 Q 66,50 95,78" stroke="steelblue" fill="none"></path> 10 <path d="M 5,22 Q 34,50 5,78" stroke="steelblue" fill="none"></path> 11 <circle cx="84" cy="50" r="2" fill="gray"></circle> 12 <circle cx="16" cy="50" r="2" fill="gray"></circle> 13 <polygon points="77,29 77,71 23,71 23,29" stroke="gray" fill="none" stroke-dasharray="4 1"></polygon> 14 <text font-size="10" x="93" y="58" fill="gray" font-style="italic">x</text> 15 <text font-size="10" x="43" y="8" fill="gray" font-style="italic">y</text> 16 <text font-size="10" x="42" y="61" fill="gray">O</text> 17 </svg>

四角い枠に接するはずなのですが、やはり関数ではないので接しません。
ちなみに制御点を変更して、接するようにしたのがこちらです。

svg

1<svg height="200" viewBox="0 0 100 100" width="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 2 <marker viewBox="-10 -5 10 10" markerWidth="5" markerHeight="5" id="mk" refX="0" refY="0" orient="auto"> 3 <polyline points="-10,3 0,0 -10,-3" stroke="gray" fill="none" stroke-width="2"></polyline> 4 </marker> 5 <line x1="2" y1="50" x2="98" y2="50" stroke="gray" marker-end="url(#mk)"></line><!--x軸--> 6 <line x1="50" y1="98" x2="50" y2="2" stroke="gray" marker-end="url(#mk)"></line><!--y軸--> 7 <line x1="5" y1="15" x2="95" y2="85" stroke="gray"></line><!--漸近線--> 8 <line x1="5" y1="85" x2="95" y2="15" stroke="gray"></line><!--漸近線--> 9 <path d="M 95,22 Q 59,50 95,78" stroke="steelblue" fill="none"></path> 10 <path d="M 5,22 Q 41,50 5,78" stroke="steelblue" fill="none"></path> 11 <circle cx="84" cy="50" r="2" fill="gray"></circle> 12 <circle cx="16" cy="50" r="2" fill="gray"></circle> 13 <polygon points="77,29 77,71 23,71 23,29" stroke="gray" fill="none" stroke-dasharray="4 1"></polygon> 14 <text font-size="10" x="93" y="58" fill="gray" font-style="italic">x</text> 15 <text font-size="10" x="43" y="8" fill="gray" font-style="italic">y</text> 16 <text font-size="10" x="42" y="61" fill="gray">O</text> 17 </svg>

厳密な曲線じゃないけど、方法がなかったらこっちでいいかなと思っています。
もし方法があれば教えてください。できればSVGで解決したいと思っています。
しかし、JSでもできるのであれば、それも教えていただけると助かります。
サインカーブもできれば実現したいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikadzuchi

2019/09/23 11:37

> 放物線は2次関数なのでベジェ曲線で定義可能です。 そんなことはありません。ベジエ曲線と放物線は別物です。 どのような曲線も近似的にしか再現できません。
suzunox

2019/09/25 10:37

僕も最初はそう思っていましたが、そうではないようです。 wikipediaによると、n個の制御点でn-1次式の関数の曲線を作ることができると書かれています。 実際僕もdesmosを使って本当にそうなるか実験してみました。これがそのurlです。 https://www.desmos.com/calculator/8tqmfxlpic 紫の点がベジェ曲線の軌跡ですが、放物線に常に接していることがわかると思います。(高1の時に実験したものなのでかなりお粗末ですが)
suzunox

2019/09/25 10:41

https://postd.cc/bezier-curves/ ここにベジェ曲線のことについてわかりやすく書いているので参考にしてください。 このページを参考にして紫の点の軌跡をプログラムしました。
ikadzuchi

2019/09/25 12:14

すみません、「2次関数」と「2次方程式」や「2次曲線」を混同し、放物線以外にも2次関数があると勘違いしていました。 確かに放物線はベジエ曲線で表せそうです。申し訳ありませんでした。
guest

回答1

0

自己解決

javascriptで1ずつの座標を計算してsvgに代入したらとてもいい感じになりました。
下のコードをまるまるそのまま.htmlで保存してみると二つの違いがわかるとおもいます。
上が2次関数、下が双曲線です。

html

1<svg height="200" viewBox="0 0 100 100" width="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 2 <marker viewBox="-10 -5 10 10" markerWidth="5" markerHeight="5" id="mk" refX="0" refY="0" orient="auto"> 3 <polyline points="-10,3 0,0 -10,-3" stroke="gray" fill="none" stroke-width="2"></polyline> 4 </marker> 5 <line x1="2" y1="50" x2="98" y2="50" stroke="gray" marker-end="url(#mk)"></line><!--x軸--> 6 <line x1="50" y1="98" x2="50" y2="2" stroke="gray" marker-end="url(#mk)"></line><!--y軸--> 7 <line x1="5" y1="15" x2="95" y2="85" stroke="gray"></line><!--漸近線--> 8 <line x1="5" y1="85" x2="95" y2="15" stroke="gray"></line><!--漸近線--> 9 <path d="M 95,22 Q 66,50 95,78" stroke="steelblue" fill="none"></path> 10 <path d="M 5,22 Q 34,50 5,78" stroke="steelblue" fill="none"></path> 11 <circle cx="84" cy="50" r="2" fill="gray"></circle> 12 <circle cx="16" cy="50" r="2" fill="gray"></circle> 13 <polygon points="80,27 80,73 20,73 20,27" stroke="gray" fill="none" stroke-dasharray="4 1"></polygon> 14 <text font-size="10" x="93" y="58" fill="gray" font-style="italic">x</text> 15 <text font-size="10" x="43" y="8" fill="gray" font-style="italic">y</text> 16 <text font-size="10" x="42" y="61" fill="gray">O</text> 17</svg> 18<div id="svgjs"></div> 19<script> 20 let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); 21 svg.setAttribute('width', '200'); 22 svg.setAttribute('height', '200'); 23 svg.setAttribute('viewBox', '0 0 100 100'); 24 let root; 25 let plus = '<path d="M 96,23 L'; 26 let minus = '<path d="M 4,23 L'; 27 28 for(var i = 24; i <= 77; i++) { 29 root = 9 * Math.sqrt((Math.pow(((3 * i / 10) - 15), 2) / 49) + 1); 30 plus += ' ' + String(Math.round((root + 15) * 100 / 3) / 10) + ',' + String(i); 31 minus += ' ' + String(Math.round((15 - root) * 100 / 3) / 10) + ',' + String(i); 32 } 33 console.log(root); 34 console.log(minus); 35 plus += '" stroke="steelblue" fill="none">'; 36 minus += '" stroke="steelblue" fill="none">'; 37 svg.innerHTML = '<marker viewBox="-10 -5 10 10" markerWidth="5" markerHeight="5" id="mk" refX="0" refY="0" orient="auto">' 38 + '<polyline points="-10,3 0,0 -10,-3" stroke="gray" fill="none" stroke-width="2"></polyline>' 39 + '</marker>' 40 + '<line x1="2" y1="50" x2="98" y2="50" stroke="gray" marker-end="url(#mk)"></line>' 41 + '<line x1="50" y1="98" x2="50" y2="2" stroke="gray" marker-end="url(#mk)"></line>' 42 + '<line x1="5" y1="15" x2="95" y2="85" stroke="gray"></line>' 43 + '<line x1="5" y1="85" x2="95" y2="15" stroke="gray"></line>' 44 + '<circle cx="84" cy="50" r="2" fill="gray"></circle>' 45 + '<circle cx="16" cy="50" r="2" fill="gray"></circle>' 46 + '<polygon points="80,27 80,73 20,73 20,27" stroke="gray" fill="none" stroke-dasharray="4 1"></polygon>' 47 + '<text font-size="10" x="93" y="58" fill="gray" font-style="italic">x</text>' 48 + '<text font-size="10" x="43" y="8" fill="gray" font-style="italic">y</text>' 49 + '<text font-size="10" x="42" y="61" fill="gray">O</text>' 50 + '<g id="plus"></g>' 51 + '<g id="minus"></g>'; 52 svg.getElementById('plus').innerHTML = plus; 53 svg.getElementById('minus').innerHTML = minus; 54 document.getElementById('svgjs').appendChild(svg); 55</script>

投稿2019/09/02 03:14

suzunox

総合スコア80

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問