Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make-solid-of-revolution した物体の表示がおかしい. #583

Open
k-okada opened this issue Sep 4, 2020 · 5 comments
Open

make-solid-of-revolution した物体の表示がおかしい. #583

k-okada opened this issue Sep 4, 2020 · 5 comments

Comments

@k-okada
Copy link
Member

k-okada commented Sep 4, 2020

https://gist.github.com/k-okada/a0c03e639ff230f4f6e28f2310fa6602#file-original-mac-cup
のプログラムを実行すると

Screenshot from 2020-09-01 14-37-52

このように2つの物体の間がおかしな描画をしてしまいました.もう一度(send *mc-cup-1* :transform (make-coords :pos #f(1000 0 0) :rpy #f(0 0 0)) :world)を実行すると

Screenshot from 2020-09-01 14-47-27

このように間の部分と一緒に動きます.この原因について教えていただけると助かります.

@mqcmd196

@k-okada
Copy link
Member Author

k-okada commented Sep 4, 2020

これは数年に一回でてくるんですが,
https://gist.github.com/k-okada/a0c03e639ff230f4f6e28f2310fa6602#file-okada-mac-cup
みたいに,

        (setq mc-cup-body (make-solid-of-revolution (list (float-vector 0 0 2) (float-vector 30 0 2) (float-vector 43 0 130) (float-vector 45 0 130) (float-vector 30 0 0) (float-vector 0 0 0))))

と引数をlist + float-vector で書くのが吉です.

これは2つ?3つ?問題があって,このやって見せてくれた例を見ると,一回画面に表示したら,その後動かしたものは最初の表示のままになる.これは,表示するときに実際に描画するのは1回だけで,あとは,OpenGLのキャッシュにいれて呼び出すhttp://www.songho.ca/opengl/gl_displaylist.html をつかっているので,

(setq *mc-cup-1* (instance mc-cup :init))
(setq *mc-cup-2* (instance mc-cup :init))
(objects (list *mc-cup-1* *mc-cup-2*)))                                                                                                                                                                                     
(send *mc-cup-1* :transform (make-coords :pos #f(1000 0 0) :rpy #f(0 0 0)) :world)
(send *mc-cup-2* :transform (make-coords :pos #f(0 0 0) :rpy #f(0 0 0)) :world)
(objects (list *mc-cup-1* *mc-cup-2*)))

とすると,見た目ちゃんと動くように成るはずです.が,これは余り本質的な解法ではなくて,
Eusのモデルは:verticesでもっているんだけど,物体を動かすとこれもついてきます(これがOpenGLと違う).ただ,ついてくるのは幾つか条件があって,毎回物体原点を移動するたびに動かすのはアレなので,明示的に:worldcoordsが呼ばれたときに移動させるというのがあります.なので,

(setq *mc-cup-1* (instance mc-cup :init))
(setq *mc-cup-2* (instance mc-cup :init))
(send *mc-cup-1* :transform (make-coords :pos #f(1000 0 0) :rpy #f(0 0 0)) :world)
(send *mc-cup-2* :transform (make-coords :pos #f(0 0 0) :rpy #f(0 0 0)) :world)

(print (list (elt (send (car (send *mc-cup-1* :bodies)) :vertices) 0) (elt (send (car (send *mc-cup-1* :bodies)) :vertices) 79)))
(print (list (elt (send (car (send *mc-cup-2* :bodies)) :vertices) 0) (elt (send (car (send *mc-cup-2* :bodies)) :vertices) 79)))

(print (mapcar #'(lambda (x) (elt x 0)) (send (car (send *mc-cup-1* :bodies)) :vertices)))
(print (mapcar #'(lambda (x) (elt x 0)) (send (car (send *mc-cup-2* :bodies)) :vertices)))

とすると,

(#f(0.0 0.0 0.0) #f(0.707107 -0.707107 2.0))
(#f(0.0 0.0 0.0) #f(0.707107 -0.707107 2.0))
(0.0 27.7164 21.2132 11.4805 -2.719644e-13 -11.4805 -21.2132 -27.7164 -30.0 -27.7164 -21.2132 -11.4805 2.848232e-14 11.4805 21.2132 30.0 27.7164 41.5746 31.8198 17.2208 -4.079467e-13 -17.2208 -31.8198 -41.5746 -45.0 -41.5746 -31.8198 -17.2208 4.272348e-14 17.2208 31.8198 45.0 41.5746 39.7268 30.4056 16.4554 -3.898157e-13 -16.4554 -30.4056 -39.7268 -43.0 -39.7268 -30.4056 -16.4554 4.082466e-14 16.4554 30.4056 43.0 39.7268 27.7164 21.2132 11.4805 -2.719644e-13 -11.4805 -21.2132 -27.7164 -30.0 -27.7164 -21.2132 -11.4805 2.848232e-14 11.4805 21.2132 30.0 27.7164 1.0 0.92388 0.707107 0.382683 9.494108e-16 -0.382683 -0.707107 -0.92388 -1.0 -0.92388 -0.707107 -0.382683 -9.065481e-15 0.382683 0.707107 0.92388)
(0.0 27.7164 21.2132 11.4805 -2.719644e-13 -11.4805 -21.2132 -27.7164 -30.0 -27.7164 -21.2132 -11.4805 2.848232e-14 11.4805 21.2132 30.0 27.7164 41.5746 31.8198 17.2208 -4.079467e-13 -17.2208 -31.8198 -41.5746 -45.0 -41.5746 -31.8198 -17.2208 4.272348e-14 17.2208 31.8198 45.0 41.5746 39.7268 30.4056 16.4554 -3.898157e-13 -16.4554 -30.4056 -39.7268 -43.0 -39.7268 -30.4056 -16.4554 4.082466e-14 16.4554 30.4056 43.0 39.7268 27.7164 21.2132 11.4805 -2.719644e-13 -11.4805 -21.2132 -27.7164 -30.0 -27.7164 -21.2132 -11.4805 2.848232e-14 11.4805 21.2132 30.0 27.7164 1.0 0.92388 0.707107 0.382683 9.494108e-16 -0.382683 -0.707107 -0.92388 -1.0 -0.92388 -0.707107 -0.382683 -9.065481e-15 0.382683 0.707107 0.92388)

みたいに:verticesはとまったままです.なので

(send *mc-cup-1* :worldcoords) 

として同じデータを表示させると

(#f(1000.0 0.0 0.0) #f(1000.71 -0.707107 2.0))
(#f(1000.0 0.0 0.0) #f(0.707107 -0.707107 2.0))
(1000.0 1027.72 1021.21 1011.48 1000.0 988.519 978.787 972.284 970.0 972.284 978.787 988.519 1000.0 1011.48 1021.21 1030.0 1027.72 1041.57 1031.82 1017.22 1000.0 982.779 968.18 958.425 955.0 958.425 968.18 982.779 1000.0 1017.22 1031.82 1045.0 1041.57 1039.73 1030.41 1016.46 1000.0 983.545 969.594 960.273 957.0 960.273 969.594 983.545 1000.0 1016.46 1030.41 1043.0 1039.73 1027.72 1021.21 1011.48 1000.0 988.519 978.787 972.284 970.0 972.284 978.787 988.519 1000.0 1011.48 1021.21 1030.0 1027.72 1001.0 1000.92 1000.71 1000.38 1000.0 999.617 999.293 999.076 999.0 999.076 999.293 999.617 1000.0 1000.38 1000.71 1000.92)
(1000.0 27.7164 21.2132 11.4805 -2.719644e-13 -11.4805 -21.2132 -27.7164 -30.0 -27.7164 -21.2132 -11.4805 2.848232e-14 11.4805 21.2132 1030.0 27.7164 41.5746 31.8198 17.2208 -4.079467e-13 -17.2208 -31.8198 -41.5746 -45.0 -41.5746 -31.8198 -17.2208 4.272348e-14 17.2208 31.8198 1045.0 41.5746 39.7268 30.4056 16.4554 -3.898157e-13 -16.4554 -30.4056 -39.7268 -43.0 -39.7268 -30.4056 -16.4554 4.082466e-14 16.4554 30.4056 1043.0 39.7268 27.7164 21.2132 11.4805 -2.719644e-13 -11.4805 -21.2132 -27.7164 -30.0 -27.7164 -21.2132 -11.4805 2.848232e-14 11.4805 21.2132 1030.0 27.7164 1001.0 0.92388 0.707107 0.382683 9.494108e-16 -0.382683 -0.707107 -0.92388 -1.0 -0.92388 -0.707107 -0.382683 -9.065481e-15 0.382683 0.707107 0.92388)

となって, *mc-cup-1* は大体x軸方向で1000動いてくれるんですが,時々 *mc-cup-2*も釣られていて,これは#fとすると,これは定数みたいに扱われているんじゃ何か説があって,list + float-vector が吉,となります.

これ以外に,ジョイントがなければbodyset-linkでよくて,ストローとかを抜き差ししたければcascaded-link を使うと良いです.

@sktometometo

@mqcmd196
Copy link

mqcmd196 commented Sep 4, 2020

ありがとうございます.そもそもの原因がmake-solid-of-revolutionにあって,#fの何らかの仕様で一緒についてきてしまうということだったのですね.jmanualの13.1に

float-vector &rest numbers
[ 関数 ]
numbers を要素とする float-vector を新しく作る。 (float-vector 1 2 3) と #F(1 2 3) の違いに注意すること。前者は、呼ばれたときはいつでもベクトルが生成されるが、後者は読み込まれたときのみ生成される。

とありましたが, 「読み込まれたとき」の状況が発生しなかったみたいな理由なのでしょうか.

@YoheiKakiuchi
Copy link
Member

実際の動作としては、#がついているのはリードマクロで、読まれたときに値(オブジェクト)に変換されます。
(float-vector ...) は関数なので、式が評価されたらその返り値として値(オブジェクト)が返ります。
どこが問題かというと、関数(メソッド)定義内に#を書いたら、メソッド定義が呼ばれたときにオブジェクトになってしまいます。

(defun hoge () #f(0))
この式が評価されたときに#f(0)がオブジェクトになって、それを返す関数hogeが定義される。
hogeの返り値は常に同一のオブジェクトが返ってくる。

(defun hige () (float-vector 0))
この式が評価されたときに、(float-vector 0)を実行して、その返り値を返す関数higeが定義される。
higeは毎回float-vector関数を呼ぶので、違うオブジェクトが返ってくる。

ということですね。
同一のオブジェクトなので、ついてくるというより同じメモリ(オブジェクト)を参照しているということですね。

「読み込まれたときのみ」という表現でいいのか難しいですね。間違ってはいないとは思います。
なんとなく”のみ”がつくので限定的なイメージに読みそうですが、読み込みは評価より必ず前に来るので、「読み込まれたときに作られてしまう」の方がしっくりきます。

@mqcmd196
Copy link

mqcmd196 commented Sep 4, 2020

@YoheiKakiuchi ありがとうございます.かなりスッキリしました.#fは常に同一のオブジェクトが返ってくる,float-vectorfloat-vector関数を呼び出すことにより,返り値として毎回異なるオブジェクトが返ってくる,#fを関数内でやってしまうとその関数が呼ばれたときにオブジェクトになってしまうということなのですね.
「読み込まれたときのみ生成される」という言葉は読み込みされる,すなわち評価されるよりも前にできてしまっているという解釈なのですね.

@YoheiKakiuchi
Copy link
Member

#fは常に同一のオブジェクトが返ってくる,float-vectorはfloat-vector関数を呼び出すことにより,
返り値として毎回異なるオブジェクトが返ってくる,#fを関数内でやってしまうとその関数が呼ばれたときにオブジェクトになってしまうということなのですね.

#fにすると読み込んだ時にオブジェクトがつくられる。別の場所で読み込めば別のオブジェクトになる。ということですね。

「読み込まれたときのみ」でいい気がしてきました。
読み込むのは関数定義が呼ばれたときで、その時のみ生成されて、
その定義された関数を使うときには読み込まれたときに生成されたものが使われるという意味なんだね。

以下、少し書き換えました。

(defun hoge () #f(0))
この式が評価されたときに#f(0)がオブジェクトになって、それを返す関数hogeが定義される。
hogeの返り値は常に同一のオブジェクトが返ってくる。

以下のような関数定義(eusだとうまく働かないけど)

(let ((a (float-vector 0))) ;; #fの評価は一度だけ
  #'(lambda () a)
  )

(defun hige () (float-vector 0))
この式が評価されたときに、(float-vector 0)を実行してその返り値を返す関数higeが定義される。
higeは毎回float-vector関数を呼ぶので、違うオブジェクトが返ってくる。

以下のような関数定義

#'(lambda () (float-vector 0))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants