接線について

Shade 3D Standard ver.16.1.0で接線を引きたいのですが、何かよい方法はございますか?
ご指導お願い致します。

http://help.shade3d.jp/ja/support/ShadeHelp18/
の説明書には「接線ハンドル」になっているので最近のは対応されているみたいですね。

Shade15でもすでにオブジェクトスナップの「接線ハンドル」のチェックは存在するので
今更ですが16.1.0のバグか名称変更でしょうか?

Shade15のスナップ設定
17

なお「接線ハンドル」は下記の図のコントロールポイントの左右に出てる
線が「接線ハンドル」だと思うのでお望みのこととはちょっと違うきがします。
(ライン上のチェックが入ってればオブジェクトにスナップするんではなかろうかと)
02

お望みであろう、滑らかに円の曲線と線形状を補完する形での
接線機能はShade17以降のNURBSモデラーで対応しているようです。
(マニュアルの 「円の外接線」参照)
16以前ですと、標準機能では厳しそうです。どなたか3rdパーティの方がスクリプトを
作られていれば可能かもしれません。

別途2D-CADソフト、illustratorなどのベクトルベースのソフトをお持ちでしたら、
そちらで作成したものをeps,dxfなどでインポートすることができます。

ものすごい誤差のある近似でよければ線形状をコントロールポイントの選択状態にしておき
片方のエンドポイントを円に近づければそれっぽくは出来るのかなと。

他にベターな回答があることを期待しつつ。

15%E3%81%AE%E3%82%B3%E3%83%92%E3%82%9A%E3%83%BC

ご回答ありがとうございます。
開いた線で接線ハンドルの練習をしたほうがよさそうですね:thinking:
それとスクリプトの練習をしてみたのですが、挫折しそうです:confounded:
拡大していくとあいませんでした:sob:

#正面図XYで作業
#円1を作成しておく
#円1外に任意の点Aを指定しておく
#Aから円1に引いた接線の交点をSとTとする

import math
A=xshade.scene().current_cursor_position #円1の中心点Pを調べる
P=xshade.scene().active_shape().center #ベクトルAP
dotA=(P[0]-A[0],P[1]-A[1], P[2]-A[2])
dotQP=(dotA[0]/2.0,dotA[1]/2.0,dotA[2]/2.0) #点QをAPの中点としてベクトルQP
AP=math.sqrt(dotA[0]**2.0+dotA[1]**2.0+dotA[2]**2.0) #APの長さを求める
r=xshade.scene().active_shape().radius[0] #円1の半径
Q=(A[0]+dotA[0]/2.0, A[1]+dotA[1]/2.0, A[2]+dotA[2]/2.0) #点Qの座標

kSQP=math.acos( (((AP/2.0)2.0)*2.0-r2.0)/(2.0*((AP/2.0)**2.0)))

dotQS=( dotQP[0]*math.cos(kSQP)-dotQP[1]*math.sin(kSQP),dotQP[0]*math.sin(kSQP)+dotQP[1]*math.cos(kSQP),0)
print AP/2.0,r,kSQP
S=( Q[0]+dotQS[0],Q[1]+dotQS[1],Q[2]+dotQS[2])
print S

xshade.scene().begin_creating()
xshade.scene().begin_line(None, 0)
xshade.scene().append_point(A, None, None, None, None)
xshade.scene().append_point(P, None, None, None, None)
xshade.scene().end_line()
xshade.scene().end_creating()

xshade.scene().create_disk(None, Q, AP/2.0, 2)

xshade.scene().begin_creating()
xshade.scene().begin_line(None, 0)
xshade.scene().append_point(A, None, None, None, None)
xshade.scene().append_point(S, None, None, None, None)
xshade.scene().end_line()
xshade.scene().end_creating()

#xshade.scene().begin_creating()
#xshade.scene().begin_line(None, 0)
#xshade.scene().append_point([-110, -20, 0], None, None, None, None)
#xshade.scene().append_point([8.98413, 241.425, 0], None, None, None, None)
#xshade.scene().append_point([170.711, 270.711, 0], [67.8224, 347.021, 0], [273.6, 194.4, 0], None, None)
#xshade.scene().end_line()
#xshade.scene().end_creating()

%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3

アナログに昔ながらの図学の作図法で試みましたが、交点がオブジェクトスナップされないせいなのか
若干ずれますねー。

やってることはスクリプトと同じだと思いますが。

1.円の中心点Pから任意の点Aを通る線分を引く。
2.引いた線の2等分線の垂線を引いて点Qを出す。
3.点Qから接点Sを結ぶ円を作る。
4.点Sと点Aを結ぶ。

【点Aの拡大図】

苦手なスクリプトですが、ネットをひとしきりしらべてなんとか形になりました。

http://shogo82148.github.io/homepage/memo/geometry/point-circle.html

↑の計算式を利用させていただきました。

ただし原点(0,0)に円がある場合のみなので、任意の点を中心(a,b)とした場合は原点からの座標さを
調べて出た数値分できた線形状を移動させる処理が必要ですかね。

あと拡大するとずれてるように見えますが、円の方に同じ座標位置でコントロールポイントを
追加する処理をしたら近似するんじゃなかろうかと。

条件としては円は「閉じた線形状」、点は「開いた線形状」であることで
Shadeのデフォルト形状「円」ではないことですかね。

##############################円外の任意の点から接線を引くスクリプト###################################

#円も線形状であること
#z軸は考慮しない

####################################################################################################

import math

scene = xshade.scene()
shape = scene.active_shape()
shapes = scene.active_shapes

#形状のコントロールポイントの数を調べて4点かつ閉じた線形状なら「円0」、1点かつ開いた線形状なら「点P」とする

for i in shapes :
   if i.number_of_control_points == 4 and i.closed == 1 :

      O= i.center_point
      Q= i.control_point(0).position

   elif i.number_of_control_points ==1 and i.closed == 0 :

      P=i.center_point 

      #タプルから各座標を抽出

      xo = O[0]
      yo = O[1] 
      xq = Q[0]
      yq = Q[1] 
      xp = P[0]
      yp = P[1]


      #計算開始

      #円Oの半径

      r =  math.sqrt(pow(xq-xo,2) + pow(yq-yo,2))

      #交点 (a1,b1)(a2,b2)の割り出し

      dx = xp - xo
      dy = yp - yo
      l2 = dx*dx + dy*dy
      D = l2 - r*r
      D = math.sqrt(D)
      a1 = r*(r*dx+D*dy)/l2
      b1 = r*(r*dy-D*dx)/l2
      a2 = r*(r*dx-D*dy)/l2
      b2 = r*(r*dy+D*dx)/l2

      #描画開始
      #接線は新規パート「接線」に格納する

      scene.begin_creating()
      scene.begin_part("接線")
      scene.begin_line(None, 0)
      scene.append_point([xp,yp,0], None, None, None, None)
      scene.append_point([a1+xo,b1+yo,0], None, None, None, None)
      scene. end_line()
      scene.begin_line(None, 0)
      scene.append_point([xp,yp,0], None, None, None, None)
      scene.append_point([a2+xo, b2+yo,0], None, None, None, None)
      scene.end_line()
      scene.end_part()
      scene.end_creating()

      #この辺に円に交点のコントロールを加えるスクリプトいれたいよね?
      
      break

   else:
      #条件以外の場合は終了
      xshade.show_message_box('''
      4点で構成された閉じた線形状の「円」と
      開いた線形状の「点」を選んでください''',0)
      break


スクリプトのところが勝手にアスタリスク省略されたり改行が
ずれたりしてますね。-o-???


整形済みテキストでくくったらなおりましたね。
ついでにできた接線をパートに格納するようにしたり、
原点以外でも使えるようにしたり。

本当はさらに円に交点を追加できれば良いのですが、
コントロールポイントの追加は座標値ではなくて各コントロール番号のインデックスの割合でしか
指定できないようです。(コントロールポイント0と1の中間点なら0.5みたいな)

ということは線形状の交点を囲む2点間のベジェ曲線の長さを調べて交点と2点間の割合を
調べてそこに追加をする指示を出さないといけなくなって微積分とか出てくると脳がパンクするのと

だんだん開発フォーラムネタになってきたきがするのでこの辺で・・・・。