;************************************************************************
;* [CMFAO] AME 6602 ACQUISITION DES DONNÉES SPATIALES
*
;* [GRCAO] Claude Parisel
*
;* Mars 1999
*
;************************************************************************
; MAKE-PERS
; construit la matrice de transformation perspective en considérant
; la projection sur un plan passant par CV (centre de vision) et
; perpendiculaire à la ligne de visée ob-cv. La pers est
prise à
; partir de l'observateur ob
; pour cela toute la scène est déplacée telle que
le tableau est en
; XOY, le CV à l'origine et l'observateur sur OY positif
;------------------------------------------------------------------------
; MAT1 Matrice de translation de la scène
à l'origine
; MAT2 Matrice de rotation pour ramener l'observateur
sur OY
; Matpers Matrice de transformation de la scène en perspective
; Mattrans Matrice finale
; PA Position de l'obs après
translation à l'origine
; PB Position de l'observateur après
rotation sur OZ
; PC Position de l'observateur après
rotation sur OY
; d Distance observateur/centre
de vision
; TZ Angle de rotation autour de
OZ
; TY Angle de rotation autour de
OY
; PZ Point à la verticale
de l'origine
; ROTANG Angle de rotation de l'image pour mettre PZ vertical
;------------------------------------------------------------------------
(defun make-pers (ob cv / mat1 mat2 matpers pa pb pc xpa ypa zpa
xpb ypb zpb d tz ty pz rotang)
;----------------------------
;translation du cv à l'origine
;----------------------------
(setq mat1 (make-trans0 cv))
(setq pa (normal (ptmat (normal ob) mat1)))
(setq xpa (car pa) ypa (cadr pa) zpa (caddr pa))
;----------------------------
;calcul de la distance ob-cv
;----------------------------
(setq d (sqrt (+ (* xpa xpa)(* ypa ypa)(* zpa zpa))))
(setq pz (list 0.0 0.0 50.0 1.0))
;----------------------------
;calcul des matrices de rotation
;----------------------------
(if
(/= d 0.0)
(progn
(if
(and (= xpa 0.0)(= ypa 0.0));obs
sur OZ -> rien
(setq mat2 (mat-i 4) pb pa)
(progn
(if
(=
xpa 0);obs dans YOZ -> -90°/OZ
(setq
tz 90.0)
(setq
tz (rad2deg (atan (/ ypa xpa))))
)
(setq mat2 (mat-rotz
(- tz)));obs ramené dans XOZ
(setq pb (normal
(ptmat pa mat2)));nouvelle position de obs
(setq xpb (car
pb) ypb (cadr pb) zpb (caddr pb))
(if
(=
zpb 0.0);obs sur OX -> -90°/OY
(setq
ty 90.0)
(setq
ty (rad2deg (atan (/ xpb zpb))))
)
(setq mat2 (mat-mul
mat2 (mat-roty (- ty))));obs sur OZ
(setq pc (normal
(ptmat pb mat2)));nouvelle position de obs
)
)
)
)
;----------------------------------
;positionnement du plan XY à l'endroit [z>0] ou vue
du dessus
;----------------------------------
(if
(< (caddr pc) 0.0)
(progn
(setq mat2 (mat-mul mat2 (mat-roty 180.0)))
(setq pc (ptmat pc mat2))
)
)
;----------------------------------
;calcul de la perspective
;----------------------------------
(setq matpers
(list
(list 1.0 0.0 0.0 0.0)
(list 0.0 1.0 0.0 0.0)
(list 0.0 0.0 0.0 (/ 1.0 (- d)))
(list 0.0 0.0 0.0 1.0)
)
)
;matrice totale
;----------------------------------
(setq mattrans
(mat-mul
(mat-mul
mat1
mat2
)
matpers
)
)
;-----------------------------------
;perspective de la verticale à l'origine
;-----------------------------------
(setq pz (normal (ptmat (normal pz) (mat-mul mat2 matpers))))
(setq pz (reverse (cdr (reverse pz))))
;-----------------------------------
;redressement de l'image [verticale // à OY]
;-----------------------------------
(if
(> (car pz) 0.0)
(setq rotang 90.0)
(setq rotang (- 90.0))
)
;----------------------------------
;retour de fonction
;----------------------------------
(mat-mul mattrans (mat-rotz rotang))
)
;---------------------------------------------------------------------
;
Exemple:
; Command: (make-pers (list
0.0 0.0 0.0)(list 1.0 2.0 3.0))
; ((0.894427 -0.358569
0.0 0.0714286) (-0.447214 -0.717137 0.0 0.142857)
; (0.0 0.597614
0.0 0.214286) (2.22045e-016 -4.44089e-016 0.0 1.11022e-016))
;---------------------------------------------------------------------
|