Les fonctions: MAKE-PERS.LSP

;************************************************************************
;* [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))
;---------------------------------------------------------------------