[Face-Wizard] 

 [Inkscape] 
 
 [Potrace] 
 
 [Tablet_Renew] 
 
 [MY_CGs] 
J Inkscapeの図形スナップと変形

■ 選択ツール使用時のスナップポイント
例えば、選択範囲に接するノードが0個〜2個のとき選択ツールでもNode to Nodeが行えたりしますが、できない形状もあります。能書きはいいから結論へ

例えばコレ。
クローバーの葉っぱみたいな物はコーナーポイント3つで描いてあります。
下図は見やすくするためにOutlineモードで表示しています。

ガイドは後から確認のために引いた物で、以下全てガイドのスナップはoffの状態としています(スナップ設定はA+Cのみで閾値は10以下にしています)。

選択ツールを使ってノードをノードにスナップする実験をしてみました。
選択範囲に接するノードが1つも無く、ノード間を結んだ直線(セグメントでなく)が水平・垂直ならば全てのノードがノードにスナップします。

ついでに図のA地点(=ノードを通る水平線・垂直線の交点)もノードにスナップします。また選択範囲にノードが接していないので選択範囲の角はスナップしません。
3つのノードの直角三角形を崩してみました。
すると、ノードがスナップするのは図のbだけになり、ノードa,cはスナップしません。
図の向きで言うとノードaをbより上に、cをbより右に移動すると、bはスナップしなくなりa,cはスナップします。

つまり2つのセグメントが選択範囲の辺に接していて、その辺の狭角から見てノードから下ろした垂線が近い方のノードがスナップするようです。ワケワカメ。
また上と同じようにノードを通る水平線・垂直線の交点(図A,B,C)もノードにスナップします。
実際にa,cをbより外に移動してみると、予測通りbはスナップせず、ノードa,cはスナップします。

ところが、今度は直交点Cはスナップするのですが、b,cの直交点はには反応せず、a,cの直交点Dがスナップします。なーんで?

試しにノードbを□aCcDの範囲内から外して大きくずらしてみた。

結果、ノードaはbおよびcよりも内なのでスナップする、bはcより内だけどaより外なのでスナップしない、cはa,bどちらから見ても外なのでスナップしない。
直交点(A=ノードa),B,C,Dは全てスナップする。

ということは、スナップできる条件に関わらず、2つのノードを結んだ線を対角線とする四角形の中にノードが存在する場合は、その□の内に入ったノードは無いものとして直交点を得る(仮)・・のだろうか。
しつこく実験。四葉のクローバーにして更にノードdを□aBCDの内に入るように移動して試してみる。

結果は図の通り、ノードaはb,dより内なのでスナップする(cは、選択範囲に接するセグメントa〜c間にノードdが存在するのでaには無関係)、a以外のノードは全て外なのでスナップしない、直交点は上と同じように□aBCDの内に入るノードdは無視されて、B,C,Dがスナップする。

これでdを直線aDより上に持っていくと、全てのノードが他のノードに対して外になるので4つの直交点でしかスナップしなくなります。
またこの図形を約45°回転して2対のノードを水平・垂直に整列すると4つのノードにのみスナップするようになります。



■ 結論
長くなるので端折ります。
選択ツールでNode to Nodeが可能な条件を持つノードは、上図の場合Cだけです。
スナップできるポイントは他には、垂線c'とノードAを通る水平線の交点、ノードAを通る水平線と垂線b'の交点、垂線b'とノードCを通る水平線の交点の、計4ヵ所がスナップします。

条件とは、図の向きで言うとノードCよりも下に他のノードが無いこと、および垂線c'より左に他のノードが無いこと、だけのようです。

要するに、Cに90°角にあわせて三角定規を当てがったとき、定規の底辺、垂直辺よりもはみ出たノードが無ければ良いので、セグメントがはみ出ている分には問題なくスナップします。

ノードC〜B,B〜A間は、いくつノードがあっても、常に選択範囲の(図では)右辺に最も近いノードBとCの直交点がノードにスナップします。
ノードBは、選択範囲に接していてもいなくても一緒です。
ノードBが存在しなければ次に近いノードが、もしノードAの垂線とセグメントの交点(ノードCから見て最初の交点)から、ノードAまでの間にBを含めたノードが存在しなければ、ノードAの垂線a'とCを通る水平線の交点がスナップします。セグメントがa'より右に出っ張っていたとしても同じです。

どうやら選択ツールでのスナップの定義は以下の2通り(図形を除く)と言えるようです。
  • 選択範囲の1辺からの距離が最も短いノードを始点とする、その1辺に対して平行な補助線1を引き、補助線1に対して鉛直な補助線2をノードからの距離 n に引いたとき、補助線2上の1点と一致する別のノードが1つ以上存在し、かつ n がノードから最も離れている時、補助線1,2の交点はスナップする。

  • 補助線2上の1点と一致するノードが存在しない、または n = 0 ならば、そのノード自体がスナップする。
  • 以上のことから、パスを構成するノードが2つ以上あり、その全てが水平・垂直線上に並んでいない全てのオブジェクトのスナップポイント(ノード含む)は常に4ヵ所であると言えます(パス化前の円/楕円を除く)。
    選択範囲の辺に近いノードを通る最も面積が大きい四角形の4つ角とも言えるかもしれない。

    例えばこういう図形でも選択ツールでノードがスナップします(矢印の先の円の中心がスナップポイントです)。


    選択範囲の辺AB・CD側のノードは垂直方向に、辺AD側のノードは水平方向に整列してあります。
    補助線1と鉛直線との"交点が最も遠い"場所なので、スナップポイントの間にあるノードはスナップしません。
    また左上のスナップポイントは選択範囲に接していませんが、辺BCに向かってスライドしていった補助線2が、選択範囲にぶつかるまでの間にノードを見つけられないのでスナップします。
    右上のポイントも同じ様に、最も遠いノード同士の直交点が選択範囲より内側なのでポイントは内側にあります。

    ノード0個のオブジェクトはありえないので、では例外の、ノード1つのパスとは。
    形状は限定されますが、この手の水滴状の形はノード1つで描けます。
    描き方は1点目(始点)をぐいっと長めにドラッグして、2点目を始点に一致させるだけです。グリッドを利用してハンドル長・角度を左右同じにすれば図のような左右対称形にもなります。

    この場合ノードが1つなのでA+Cの設定ではノードしかスナップしません。

    ということは、ポリゴンの角を覆うように隠してしまえば、6角形でも頂点のスナップが(選択ツールで)可能になるのでは?
    (というかソレができる方法が知りたくてこんなページを書いていたのですが)

    と思ってやってみたけど、駄目デシタ・・・orz
    グループ化してもパス連結しても、結局はその「グループ内での全ノード」に対して、上の定義が適用されてしまう。

    なんてこったい。
    例えばこんな風にパスの内部を差分でくり抜いたとしても
    こんな風に離れた場所のオブジェクトをグループ化しても、やっぱりスナップする場所は4ヵ所しかないですのよ。

    ※こんな風にグループ化したオブジェクトのノードを選択する事はできません(できたらいいのになぁ)。

    図は全て赤い印がスナップポイントです。

    ここまでで分かったこと。傾けた正6角形の、選択範囲の辺に接しない頂点を選択ツールでスナップするのはムリ!(どんなことをしても必ず隣合せた角が選択範囲の1辺に接するので)。

    選択範囲に接する6角形の頂点を、選択ツールでスナップするなら実は可能です。
    ゆがみ(限定角)を使って頂点を選択範囲の角に一致するようにして、スナップしてから元の形にゆがみ直せば良い(というか形を維持したままスナップするならノードツールでやれば良いだけなんですが)。


    おさらい

    オブジェクトの一部をどこかにスナップさせたいとき、目的のオブジェクトに自身の「選択範囲の角」と接するノードが有れば、選択ツールでそのノードを相手側のノードまたはパス上にスナップ可能ですが、それ以外の場合はノードツールを使うのが基本のようです。

    例えばを矩形で、をベジェツールで適当に(斜めに)描き、それらをスナップさせたいとき。
    (ガイド・グリッドは非表示の状態とします)


    選択ツールの場合:

    の角をにスナップする場合、矩形は4つの角が選択範囲の角と一致しますからA+Cの設定で、どの角でも、が傾いていたとしても、の頂点(=ノード)にも辺(=セグメント)にもスナップできます。矩形のノードがスナップしている様に見えますが、実際には選択範囲の角(=スナップポイント)がスナップしています。
    例えば こんなふうに角を切り欠いてもスナップポイントは変化しません。
    またスナップさせる相手がのような単純な形で頂点が鋭角ならA+B+Cの設定でセグメントにもノードにもスナップできます。

    のセグメント上の1点をの頂点にスナップすることは選択ツールではできません(傾きのないなら角を頂点にスナップさせてから[Ctrl]+ドラッグで期待した操作を実行できます)。

    にスナップする場合も同じように、斜めにしたは選択範囲の角に接する頂点が1つだけですから、選択ツールではその頂点しか矩形のノードにはスナップできません。
    目的のオブジェクトがの場合は、どれだけ傾けても常に3つの頂点が選択範囲に接しますから、相手が水平線、垂直線を持つ矩形であれば全てのノードを矩形のセグメント上にスナップできます。

    オブジェクトのストローク幅 > 0 のときは少し特殊で、選択範囲とはオブジェクトの最大幅x最大高さを囲う四角形で、ストロークとは常にセグメントを中心線とする幅のあるラインですから、当たり前ですが直立する矩形であれば1辺あたりストローク幅÷2の分だけ選択範囲が広がります。
    それでもなお、A+BまたはA+Cの設定の時は、あくまでストローク幅 = 0のときのスナップポイントがスナップします。
    つまりセグメントより外側のストロークが相手側に重なります。
    例えば▲のストローク幅が太めで、オブジェクトのZ順が■より下層にあるとき、▲の頂点を■の角にスナップさせたつもりでも▲の頂点が■に潜り込んだ形になってしまいます。

    こうした場合には@+Bまたは@+Cの設定にして、バウンディングボックス(=選択範囲)を相手にスナップさせれば良いのですが、Snap bounding boxes to objectsは選択範囲の角しかスナップできない上、スナップさせる相手もストローク幅が有った場合、これはもうどうしようもありません。
    なぜならNode to bounding boxやbounding box to bounding boxの設定が無いからです。
    ストローク外周にストローク外周をスナップさせるのに有効と思われる手段は(ストロークをパスに変換する以外の方法で)、
    1). バウンディングボックスをセグメントやノードにスナップしたあと、整列ダイアログでスナップされた側を基準に面を合わせる(これはスナップしたい場所が相手の選択範囲と一致する場合のみ)
    2). やや不正確ですが[Alt+矢印キー]で微小移動(これが一番楽。256倍までZoomして行えばほぼ正確)
    3). スナップする前に、相手側をコピーしてストロークとFillを分割→最低2枚以上のオブジェクトが生成されるので外周側を残して削除→そこにスナップ(スナップ先の形状の複雑さによっては[Alt+矢印]より不正確)
    4). スナップしたい側のバウンディングボックスの頂点座標はソースから得られるのでそこに正確にガイドをタテヨコともに設置→相手側のノードを全選択→Node to Node

    くらいしか思いつきませんでした。

    ※実際には▲のストロークの頂点は連結リミットによって選択範囲よりはみ出ているので、(1)(4)の方法では頂点は潜り込んだままになります。


    ノードツールの場合:

    ※矩形のr制御点以外の2点・円(+楕円)・星(+ポリゴン)などの図形は、パスに変換前と変換後でノードツールの機能が切り替わるため、変換前はノードツールではスナップできません。ポリゴンで▲や■を描いた時も同様です。

    ■のセグメント上の1点を▲の頂点にスナップするには、セグメント上の目的の場所にノードを追加([Ctrl+Alt]+クリック)→全ノード選択→目標の頂点にドラッグで可能です。
    例えば■の辺の中心を▲の頂点にスナップするには、■の辺の2つのノードを選択→[Insert]キーで正確に辺の(2点間の)中心にノードを打てます。

    ノードツールを使用する時は、[Ctrl+A]で選択オブジェクトの全ノードを選択状態にしてからノードを掴んで(ノード以外を掴むとセグメントが変形してしまいます)ドラッグすれば、選択ツールと同様に全体を移動でき、掴んでいる以外のノードでも相手のノードやセグメントにスナップします。
    ただし掴めるのは、たとえグループ化してあるオブジェクトでも、その中の1つのオブジェクトだけです。

    複数のオブジェクトをノードツールで掴むには、複数選択してから「パス連結」(または統合)するしかなく、スナップしてから分割してスタイルを元に戻す事になるので、コピーを連結してスナップして、元のオブジェクトをそれにスナップしてコピーを削除すると良いかもしれません。

    連結したオブジェクトでも、選択中のノードであれば掴んでいるノード以外もスナップします。


     MENU△ PAGE TOP▲

    Oct 15 2007