euslisp / jskeus

This repository contains EusLisp software developed and used by JSK at The University of Tokyo
23 stars 55 forks source link

make-prismで作った立体の面の法線ベクトルが逆になっている #454

Open chibi314 opened 7 years ago

chibi314 commented 7 years ago

make-cubeなどで作った立体の面の法線ベクトルは外向きになるようですが、make-prism関数で作った立体の面の法線方向は内側になるようです。以下、サンプルコードです

(defun view-face-normal
  (&key (tmpb obj1))
  (send *irtviewer* :draw-objects)
  (dolist (f (send tmpb :faces))
    (send *irtviewer* :draw-objects)
    (send f :draw-on :flush nil)
    (send *irtviewer* :viewer :draw-arrow
          (cadr (send f :centroid))
          (v+ (scale 50 (send f :normal)) (cadr (send f :centroid))))
    (send *irtviewer* :viewer :viewsurface :flush)
    (read-line)))

(defun test0 ()
  "正しいっぽい"
  (setq obj1 (make-cube 200 200 200))
  (objects (list obj1))
  (view-face-normal))

(defun test1 ()
  "正しいっぽい"
  (setq obj1 (make-cylinder 50 200))
  (objects (list obj1))
  (view-face-normal))

(defun test2 ()
  "正しくないっぽい"
  (setq obj1 (make-prism (list #f(100 -100 0) #f(100 100 0) #f(-100 100 0) #f(-100 -100 0)) 200))
  (objects (list obj1))
  (view-face-normal))

(defun test3 ()
  "正しくないっぽい"
  (setq obj1 (make-prism (list #f(15 0 0) #f(15 120 0) #f(-15 120 0) #f(-15 0 0) #f(-120 0 0) #f(-120 -30 0) #f(120 -30 0) #f(120 0 0)) 100))
  (objects (list obj1))
  (view-face-normal))

(warn ";; (test0)~%")
(warn ";; (test1)~%")
(warn ";; (test2)~%")
(warn ";; (test3)~%")
YoheiKakiuchi commented 7 years ago

このとき、表示どうなるんだっけ? 裏表逆転がわかるような表示になっているかな?

マニュアル P.135 の記述で、pointsの並びについて説明が無いんだけれども、 これを見ると、pointsは時計回りに設定する意図があるように思える。 そうするとどうなるかな?

, (make-prism ’(#f(1 1 0) #f(1 -1 0) #f(-1 -1 0) #f(-1 1 0)) 2.0) は,高さ 2.0 の直方体を作る。
snozawa commented 7 years ago

「法線はbodyなどの外側をむく」もまた、jmanualに実は明示的に記載をみたことがないものですが、あってますでしょうか。 @chibi314 と先ほど本件をみたあとで、qhull (euscolladaで生成されたロボット、samplerobot.lを目視確認)なども法線は外側のようで、今のところmake-prismだけが方式が違ってそうです。

YoheiKakiuchi commented 7 years ago

うーんとそんな根源的な話でなくて、面が反対だと思ったら、pointsをrevertしたら正しいと思う方向に出るよということです。

以下はmake-cubeと同じ方向に出ているように見える。

 (make-prism (list #f(100 100 0) #f(100 -100 0) #f(-100 -100 0) #f(-100 100 0)) 200)

で、この記法がマニュアルに記載されているので、普通に外側に法線が向いて欲しいなら、その順でpointsを並べる必要がある。 コードをちゃんと見たわけでないけど、pointsの並びでオモテウラが決まってしまってそれをただスウィープしているんだと思う。 面を表す点は時計回りに並べるか半時計回りに並べるかで、面の方向が変わる場合が多いけど、 cwとccwと法線の方向は使う側の定義次第なんじゃないかな?

inabajsk commented 7 years ago

cwとccwと法線の方向は使う側の定義次第なんじゃないかな?

そうです. 点列が一巡する回転方向に法線が出るようになっているので与える点列を逆順に 与えるか,点列は同じで,sweepする方向を逆にする

(defun test4 () (setq obj1 (make-prism (list #f(15 0 0) #f(15 120 0) #f(-15 120 0) #f(-15 0 0) #f(-120 0 0) #f(-120 -30 0) #f(120 -30 0) #f(120 0 0)) -100)) (objects (list obj1)) (view-face-normal))

のようにすると外を向きます.

内側を向いているのは,その立体の外側の立体を表すということで その立体よりも大きい立方体とbody+をとると,中にそのprismの穴として 空いた立方体モデルができるようになると思います.

稲葉

2017年8月28日 20:01 Yohei Kakiuchi notifications@github.com:

うーんとそんな根源的な話でなくて、面が反対だと思ったら、pointsをrevertしたら正しいと思う方向に出るよということです。

以下はmake-cubeと同じ方向に出ているように見える。

(make-prism (list #f(100 100 0) #f(100 -100 0) #f(-100 -100 0) #f(-100 100 0)) 200)

で、この記法がマニュアルに記載されているので、普通に外側に法線が向いて欲しいなら、その順でpointsを並べる必要がある。 コードをちゃんと見たわけでないけど、pointsの並びでオモテウラが決まってしまってそれをただスウィープしているんだと思う。 面を表す点は時計回りに並べるか半時計回りに並べるかで、面の方向が変わる場合が多いけど、 cwとccwと法線の方向は使う側の定義次第なんじゃないかな?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/euslisp/jskeus/issues/454#issuecomment-325324144, or mute the thread https://github.com/notifications/unsubscribe-auth/AFmr5bv6I-gGrqcqdSbdNApxeRQLYPYaks5scp4cgaJpZM4PEUkR .

chibi314 commented 7 years ago

皆さんありがとうございました。 make-prismは基本的には時計回りに定義しておいたほうがよいのですね。 勉強になりました。

k-okada commented 7 years ago

マニュアルに一言追加しておきましょう

For example, の前に the bottom face is assumed as clockwise.とかあると混乱しなかったかな? これじゃどっちが法線かわからないからダメか

Makes a prism by lifting the shape defined by bottom-points along sweep-vector. If the sweep-vector is a number, not a float-vector, it is taken as the height of the prism in the direction. Bottom points must be ordered as they define the bottom face of the body. For example, (make-prism '(#f(1 1 0) #f(1 -1 0) #f(-1 -1 0) #f(-1 1 0)) 2.0) makes a cube of height 2.0.

2017年8月29日(火) 17:48 Tomoki Anzai notifications@github.com:

皆さんありがとうございました。 make-prismは基本的には時計回りに定義しておいたほうがよいのですね。 勉強になりました。

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/euslisp/jskeus/issues/454#issuecomment-325597498, or mute the thread https://github.com/notifications/unsubscribe-auth/AAeG3EgwgfJgMHj95vWvaEZoWzthIMZZks5sc9ADgaJpZM4PEUkR .

--

◉ Kei Okada

YoheiKakiuchi commented 7 years ago

make-prismは基本的には時計回りに定義しておいたほうがよいのですね。

日本語でも伝わるか心もとない説明になりますが、 理解の仕方としては、pointsの並びで面ができて、その面(A)はprismの面として、そのまま使われる (instance face :init :vertices points で作られる面と同様な面)

このときのpointsの順と法線の方向は、ccwのならびに見える方が法線の向き。 (xy平面でccwに並べるとz軸方向に法線になる、たいていのメッシュファイルで定義はそうなっている場合が多い)

(A)面の法線の方向にsweepした時はできる面がウラ面になる。(法線が物体の内側を向くため) 法線とは逆方向にsweepした時はできる面がオモテ面になる。 というようなことだと思います。

snozawa commented 7 years ago

うーんとそんな根源的な話でなくて、面が反対だと思ったら、pointsをrevertしたら正しいと思う方向に出るよということです。

私の質問としては、 https://github.com/euslisp/jskeus/issues/455 よりの話だったかもしれません。 お伺いしたかったこととしては、単体でbodyとして使える(?)ものは、法線の向きが外側を向いているべきでしょうか。法線の向きが逆だと思ったらrevertするとして、どっちが「正」でどっちが「逆」でしょうか。 もしくは、外・内側どちらでも良いのでしょうか。

どちら向きでもbodyは作れると思いますが、

455

などの干渉計算のときには、内側・外側どっちかでないといけないような気がしました。