Aller au contenu

ligne projectee sur face 3d


Messages recommandés

Invité ingoenius
Posté(e)

bonjour, pour un lisp geometrique (vu que je suis pas un experte en mat)

 

je voulais savoir quel calcul il faut faire pour dessiner une ligne qui part d'un point P1 avec un l' angle donnée entre le point P1 et P2 et prolongée jusq'a l'intersection avec une face 3d (qui existe pas, mais de laquelle on as les 4 coordonnes des point 3d

 

pour moi c'est trop dur ;-)

merci a vous

 

Posté(e)

Salut ingoenius,

 

Ce que tu demandes pose un problème.

Il est tout à fait possible de trouver le point d'intersection entre une droite et un plan, mais une Face3d à 4 sommets n'est pas forcément plane (3 points définissent un plan).

 

Pour l'intersection entre un droite (définie par 2 points) et un plan (défini par 3 points), tu peux :

- soit faire appel à la calculatrice géométrique d'AutoCAD (commande CAL) :

;; ILP_CAL Retourne le point d'intersection de la droite définie par p1 p2
;; et du plan défini par p3 p4 p5.
;;
;; Arguments
;; p1 et p2 : les points définissant la droite dont on cherche l'intersection
;; p3 p4 p5 : les points définissant le plan
(defun ilp_cal (p1 p2 p3 p4 p5)
 (or (member "geomcal.arx" (arx))
     (arxload "geomcal")
 )
 (c:cal "ilp(p1,p2,p3,p4,p5)")
) 

 

- soit utiliser le calcul vectoriel (le code est plus long mais l'exécution 10 fois plus rapide) :

;; ILP3PTS Retourne le point d'intersection de la droite définie par p1 p2
;; et du plan défini par p3 p4 p5.
;;
;; Arguments
;; p1 et p2 : les points définissant la droite dont on cherche l'intersection
;; p3 p4 p5 : les points définissant le plan

(defun ilp3pts (p1 p2 p3 p4 p5 / x1 y1 z1 x2 y2	z2 x3 y3 z3 x4 y4 z4 x5
	y5 z5 xn yn zn sc pt)
 (mapcar 'set
  '(x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 x5 y5 z5)
  (mapcar 'float (append p1 p2 p3 p4 p5))
 )
 (setq	xn (- (* (- y4 y3) (- z5 z3)) (* (- y5 y3) (- z4 z3)))
yn (- (* (- z4 z3) (- x5 x3)) (* (- z5 z3) (- x4 x3)))
zn (- (* (- x4 x3) (- y5 y3)) (* (- x5 x3) (- y4 y3)))
 )
 (if (not
(zerop
  (setq
    sc (+ (* xn (- x2 x1)) (* yn (- y2 y1)) (* zn (- z2 z1)))
  )
)
     )
   (setq sc (/	(+ (* xn (- x1 x3)) (* yn (- y1 y3)) (* zn (- z1 z3)))
	sc
     )
  pt (list
       (+ (* sc (- x1 x2)) x1)
       (+ (* sc (- y1 y2)) y1)
       (+ (* sc (- z1 z2)) z1)
     )
   )
 )
) 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Ben moi, j'ai P1 et P2 complétement dans l'espace, il me faut une page de code complète avec des itérations pour trouver l'intersection.

Ma routine tourne tous les jours depuis 2 ans mais je fais tourner des itérations pour trouver des points les plus proches et blabla.

Il m'a fallu plusieurs jours pour coder. Avec des racines carrées et des déterminants, genre pythagore dans l'espace.

 

Si j'avais su.

Idem pour le calcul vectoriel.

 

degu'

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)

Bonjour,

 

La même chose que Gile

 

(defun ilp_perso(pt_a pt_b pt_1 pt_2 pt_3)


(setq xa(car pt_a))
(setq ya(cadr pt_a))
(setq za(caddr pt_a))
(setq xb(car pt_b))
(setq yb(cadr pt_b))
(setq zb(caddr pt_b))
(setq x1(car pt_1))
(setq y1(cadr pt_1))
(setq z1(caddr pt_1))
(setq x2(car pt_2))
(setq y2(cadr pt_2))
(setq z2(caddr pt_2))
(setq x3(car pt_3))
(setq y3(cadr pt_3))
(setq z3(caddr pt_3))
(setq xn(- (* (- y2 y1) (- z3 z1)) (* (- y3 y1) (- z2 z1))))
(setq yn(- (* (- z2 z1) (- x3 x1)) (* (- z3 z1) (- x2 x1))))
(setq zn(- (* (- x2 x1) (- y3 y1)) (* (- x3 x1) (- y2 y1))))

(setq s (/ (+ (* xn (- xa x1)) (* yn (- ya y1)) (* zn (- za z1))) (+ (* xn (- xb xa)) (* yn (- yb ya)) (* zn (- zb za)))))

(setq x_pt (+ (* s (- xa xb)) xa))
(setq y_pt (+ (* s (- ya yb)) ya))
(setq z_pt (+ (* s (- za zb)) za))

(setq pt (list x_pt y_pt z_pt))

pt

)

 

@plus

 

LB

Invité ingoenius
Posté(e)

Merci gile,

c'est SUPER trés intaressant, e trés rapide aussi

maintenat je cherche a etudier la chose

(j'oubli toujours que les face de base ont 3 vertex et pas 4)

 

 

 

Invité ingoenius
Posté(e)

genial, alors je recommance mon raisonnement, le but est de dessinner le cadre de la deformation d'une projection video sur par exemple la facade d'un immeuble, en sachant que le projecteur video est a ex 2mt du sol, mais qu'il point plus haut, donc on aurà un carre qui devient un trapeze selon l'angle de projection

 

ici le debut du lisp pour le projecteur, mais je dois trouver la facon de le corriger pour s'adapter a l'inclinaison de projection (pour l'instant ca marche seulement a plat)

 

 

fait cela, il faut integrer la partie de code de l'intersection de facon a une fois modeliser un volume tipe pour l'edifice (un carre extrudee) je puisse reconstruire la deformation de la projection

 

si interesse quelqc'un ce projet on peut avancer ensemble e sortir quelque chose d'utile

 

merci a tous pour la collaboration ;-)

 

 

 
(defun c:projDO(); elements connus DISTANCE e OPTIQUE

(defun DTR (a) (* pi (/ a 180))) ;degres en radiants
(defun RTD (a) (/ (* a 180) pi ));radiants en degres
(setvar "osmode" 3)		 ;mette  lo snap a fin e mid

 
(initget 1)			 ;controllo imput nullo
(setq Puntamento (getpoint "\nPick center of image : "));puntamento proiettore
(prompt "\nPick Projector position:")
(command "_line" Puntamento pause "" )
(setq LL (entlast))

(setq Line (entget LL))  
(setq Lamp (cdr (assoc 11 Line)))
;(setq Lamp (cdr (assoc 10 Line)))  
(initget 1);controllo imput nullo
;(command "_line" LAMP Puntamento "")	;disegna la prima linea

(setvar "osmode" 0);toglie lo snap 

(initget 1);controllo imput nullo
(setq OTTICA (getreal "\nLens?  es 0.33 :  ")) ;ottica proiettore
(setq SLIDE 1.0) ;piano ottico 
(setq distanza (distance LAMP PUNTAMENTO));distanza di proiezione

(setq INCL(angle  LAMP Puntamento));ottengo l'angolo 1 in radianti
(setq INCL_G (angtos incl 0 3));lo stesso angolo in gradi
(setq INCL_r (atof INCL_g));numero reale

;qua bisogna mettere una condizione a seconda del quadrante verso cui va la linea


;Q1

(cond
 ((>= 90 incl_r)
(setq incl_f (+ INCL_r  180 ));ottengo la dir opposta per il p p5
(setq incl_slide1 (+ 90 INCL_r ));ottengo la dir opposta per il p p6
(setq incl_slide2 (+ INCL_r 270  ));ottengo la dir opposta per il p p6
)
;Q2
(( >= 180 incl_r)
 (setq incl_f (+ INCL_r  180 ));ottengo la dir opposta per il p p5
(setq incl_slide1 (+ 90 INCL_r ));ottengo la dir opposta per il p p6
(setq incl_slide2 (- INCL_r 90  ));ottengo la dir opposta per il p p6
)
;FINE Q2

;Q3
((  >= 270 incl_r)
 (setq incl_f (- INCL_r  180 ));ottengo la dir opposta per il p p5
(setq incl_slide1 (+ 90 INCL_r ));ottengo la dir opposta per il p p6
(setq incl_slide2 (- INCL_r 90  ));ottengo la dir opposta per il p p6
)
;FINE Q3
;Q4
((  >= 360 incl_r)
 (setq incl_f (- INCL_r  180 ));ottengo la dir opposta per il p p5
(setq incl_slide1 (- INCL_r  90));ottengo la dir opposta per il p p6
(setq incl_slide2 (- INCL_r 270  ));ottengo la dir opposta per il p p6
)
(t nil)
 )
;FINE Q4


;creation des points  
(setq P5 (polar LAMP (dtr incl_f) ottica));determina il punto P5 cioé centro della slide 
(setq P6 (polar P5 ( dtr incl_slide1) (/  SLIDE 2 )));determina il punto P6 cioé un lato slide 
(setq P7 (polar P5 ( dtr incl_slide2) (/ SLIDE 2 )));determina il punto P6 cioé un lato slide

(command "_line" P6 P7 "")  ;disegna l'asse ottico
(command "_line" P6 lamp "");disegna il raggio 1
(setq Lo1 (entlast))	    ;nomino la polilinea LineaOptique1  
(command "_line" P7 lamp "");disegna il raggio 2
(setq Lo2 (entlast))	    ;nomino la polilinea  LineaOptique2

;fin dessin optique   


 
(setq ottica1 (* 100 ottica) slider (* 100 slide))
(setq immagine (/ (*  distanza slider   ) ottica1)) ;dimensione immagine ottica perfetta 

;formato immagine per stabilire l'altezza 

(initget 1 "16x9 4x3 5x4")
 	(setq screen (getkword "\ntype 16x9 4x3 5x4 ?\n"))	;determina il tipo di schermo scelto 

(cond 
  		((= screen "16x9")
	(setq ALT (* 9 (/ immagine 16)))		 
	)
  		((= screen "4x3")
	(setq ALT (* 3 (/ immagine 4)))		 
	)
  		((= screen "5x4")
	(setq ALT (* 4 (/ immagine 5)))		 
	)
 
)		 


 
(setq ALTh (/  ALT 2))	            ;hauter haut = coord Z de P10 et P12
(setq ALTb (- ALTh ( + Alth Alth) ));hauteur bas = coord Z de P11 et P13
 
 

(setq mezza (/ immagine 2 )); dim mezza immagine proiettata 

(setq P8 (polar puntamento (dtr incl_slide2) mezza )); punto ext immagine
(setq P9 (polar puntamento (dtr incl_slide1 ) mezza )); punto ext immagine


(setq P10 (list (car P9)(cadr P9) Alth));altezza schermo
(setq P11 (list (car P9)(cadr P9) Altb));altezza schermo
(setq P12 (list (car P8)(cadr P8) Alth));altezza schermo
(setq P13 (list (car P8)(cadr P8) Altb));altezza schermo
 

(command "_line" P10 P11 P13 P12 P10  "");disegna quadro immagine

 
;(command "_line" lamp P8 P9 LAMP  "");disegna i raggi
(command "_line" P10 lamp P12  "");disegna i raggi
(command "_line" P11 lamp P13  "");disegna i raggi




 


(command "_UCS" "g" "")	
(setvar "osmode" 3);rimette a 3  lo snap middle fin 
(setq im (rtos immagine  ));converto in stringa il valore dell'immagine
(setq message (strcat "la base misura " IM " metri"));unisco le stringhe
(alert message);message box col messaggio
);fine defun

Invité ingoenius
Posté(e)

oui c'est un peu fous, sourtout que j'ai dejà du mal a axpliquer ce que je veut fair, en italien l'ecrire en francais c'est une difficulté supplementaire ;-)

mais si vous pensaiz que ça peut pas etre utile alors on va pas le faire ;-(

 

Invité ingoenius
Posté(e)

Je met un exemple de ce que je voudrait programmer

 

http://www.sendbox.fr/upload/files/1c2C4d6J0h8D0h5J1e5A5b1J0c2A0i/ex1.20080926-1548.jpg

 

 

 

le but est d'indiquer au lisp les point 1 et 2 (repondre a quelque question type rapport image et optique)

et ensuite cliquer sur trois point representant la face3d du batiment et recuperer la projection comme sur l'image

 

mes problemes viennes sourtout du fait d'adapter les _ucs a la bonne rotation pendent le script , je maitrise pas bien les (entmod) ou autre chose, qui permet d'avoir les bonnes coordonnes des point dans le lisp car pendent celui ci si je change de _ucs mes variables de coordonnes de point ne sont plus correctes

 

autre chose je cherchais a faire deplacement de l'ucs e rotation de celui ci en Y mais j'arrive pas

 

ex (command "_ucs" P1 "_Y" P2 "") mais ca ne marche pas pourquoi??

merci ancore a vous ;-)

Posté(e)

pas toujours facile de récupérer en numérique ce qui ce trace assé facilement (intersection d'un plan avec une pyramide dans ton cas)

 

j'ai eu le soucis ya pas longtemps ou un menuisier me demandait de lui coté des points tous les 10cm de l'intersection d'un plan et d'un cylindre...

tracé en 3d en 5mn mais 2h pour faire le développé et le coter...

 

as tu essayer de faire la soustraction de solide plans - pyramide?

car dans ton cas, ce serai plus facile de récupérer les coordonnées des points vu (4 sommets dans tous les cas)

Invité ingoenius
Posté(e)

le fait est que ensuite je voudrait pouvoir projecter toute la grille ex un reticule de 16*9 carre si mon rapport est 16/9, dans ce cas il faut pouvoir recuperer tous les point voulus ;-(

 

le probleme principale pour moi est quand je change de _ucs pendant le script je ne sais pas le mettre a jour dans la base de donne , je sais que il y a une facon de le faire mais je l'ai j'amais utilisée , ce pour cela que j'ai suis pas parti sur la subtraction piramide boite, mais je cherche a calculer matematiquement les coordonnes des point pou ensuite tracer le ligne une par une

 

par contre si on trouve une methode meilleur c'est bien venu ;-)

 

Posté(e)

Salut,

 

Je pense avoir trouvé quelque chose en faisant faire des rotations à des vecteurs à l'aide de matrices.

 

- Si j'ai bien compris, la variable ottica correspond au "ratio de projection" (rapport entre la distance du projecteur à l'écran et la largeur de l'image

 

- Si l'axe du projecteur est bien perpendiculaire à l'écran en vue de dessus,

 

la routine ci dessous devrait fonctionner (si la dernière condition n'est pas remplie, il faudrait que l'utilisateur spécifie 2 autres points sur le plan de l'écran).

 

Une petite demo

 

(defun c:projDO	(/	 puntamento	 lamp	 ottica	 screen
	 height	 width	 ang-h	 norm	 ang_v	 aper_h
	 aper_v	 v1	 v2	 v3	 v4	 pt1
	 pt2	 pt3	 pt4
	)

 ;; Entrées utilisateur
 ;; puntamento : centre de l'image
 ;; lamp : position du projecteur
 ;; ottica : ratio de projection
 ;; screen : format de l'image

 (initget 1)
 (setq puntamento (getpoint "\nPick center of image: "))
 (initget 1)
 (setq	lamp	   (getpoint puntamento "\nPick Projector position:")
puntamento (trans puntamento 1 0)
lamp	   (trans lamp 1 0)
 )
 (initget 1)
 (setq ottica (getreal "\nLens? es 0.33: "))
 (initget 1 "16x9 4x3 5x4")
 (setq screen (getkword "\nType [16x9/4x3/5x4]:"))

 ;; Calcul des angles
 ;; ang_h : angle horizontal de l'axe de projection / axe X
 ;; ang_v : angle vertical de l'axe de projection / plan XY
 ;; aper_h : demi angle horizontal du faisceau
 ;; aper_v : demi angle vertical du faisceau
 ;; norm : normale du plan de l'écran
 (cond
   ((= screen "16x9")
    (setq height 9
   width 16
    )
   )
   ((= screen "4x3")
    (setq height 3
   width 4
    )
   )
   ((= screen "5x4")
    (setq height 4
   width 5
    )
   )
 )
 (setq	ang_h  (angle lamp puntamento)
ang_v  (atan (- (caddr puntamento) (caddr lamp))
	     (distance (list (car puntamento) (cadr puntamento))
		       (list (car lamp) (cadr lamp))
	     )
       )
aper_h (atan 0.5 ottica)
aper_v (atan (* height (sin aper_h)) width)
norm   (polar '(0 0 0) (+ pi ang_h) 1.0)
 )

 ;; calcul des vecteurs directeurs des arrêtes du faisceau (axe faisceau // axe X)
 (mapcar
   (function
     (lambda (v ah av)
(set v
     (mxv
       (mxm
	 (list (list (cos ah) (- (sin ah)) 0)
	       (list (sin ah) (cos ah) 0)
	       '(0 0 1)
	 )
	 (list (list (cos av) 0 (- (sin av)))
	       '(0 1 0)
	       (list (sin av) 0 (cos av))
	 )
       )
       '(1 0 0)
     )
)
     )
   )
   '(v1 v2 v3 v4)
   (list aper_h aper_h (- aper_h) (- aper_h))
   (list (- aper_v) aper_v aper_v (- aper_v))
 )

 ;; rotations des vecteurs suivant les angles ang_h et ang_v
 (foreach v '(v1 v2 v3 v4)
   (set v
 (mxv
   (mxm
     (list (list (cos ang_h) (- (sin ang_h)) 0)
	   (list (sin ang_h) (cos ang_h) 0)
	   '(0 0 1)
     )
     (list (list (cos ang_v) 0 (- (sin ang_v)))
	   '(0 1 0)
	   (list (sin ang_v) 0 (cos ang_v))
     )
   )
   (eval v)
 )
   )
 )

 ;; calcul des points d'intersection des arrêtes et du plan de projection
 (mapcar
   (function
     (lambda (p v)
(set p (ilp lamp (mapcar '+ lamp v) puntamento norm))
     )
   )
   '(pt1 pt2 pt3 pt4)
   (list v1 v2 v3 v4)
 )

 ;; dessin de l'image sur le plan de projection
 (mapcar
   (function
     (lambda (p1 p2)
(entmake (list '(0 . "LINE") (cons 10 p1) (cons 11 p2)))
     )
   )
   (append (DivSeg pt1 pt2 height) (DivSeg pt2 pt3 width))
   (append (DivSeg pt4 pt3 height) (DivSeg pt1 pt4 width))
 )

 ;; dessin des arrêtes du faisceau
 (foreach p (list pt1 pt2 pt3 pt4)
   (entmake (list '(0 . "lINE") (cons 10 lamp) (cons 11 p)))
 )

 (princ)
)

;; VXV (gile)
;; Retourne le produit scalaire (réel) de deux vecteurs
;;
;; Arguments : deux vecteurs

(defun vxv (v1 v2) (apply '+ (mapcar '* v1 v2)))

;; TRP
;; transpose une matrice -Doug Wilson-
;;
;; Argument : une matrice

(defun trp (m) (apply 'mapcar (cons 'list m)))

;; MXV
;; Applique une matrice de transformation à un vecteur -Vladimir Nesterovsky-
;;
;; Arguments : une matrice et un vecteur

(defun mxv (m v)
 (mapcar (function (lambda (r) (vxv r v))) m)
)

;; MXM
;; Multiple (combine) deux matrices -Vladimir Nesterovsky-
;;
;; Arguments : deux matrices

(defun mxm (m q)
 (mapcar (function (lambda (r) (mxv (trp q) r))) m)
)

;; ILP (gile)
;; Retourne le point d'intersection de la droite définie par p1 p2
;; et du plan défini par un point et sa normale.
;;
;; Arguments
;; p1 et p2 : les points définissant la droite dont on cherche l'intersection
;; org : un point queconque du plan d'intersection
;; nor : le vecteur normal du plan d'intersection

(defun ilp (p1 p2 org nor / scl)
 (if (and
(/= 0 (setq scl (vxv nor (mapcar '- p2 p1))))
(setq scl (/ (vxv nor (mapcar '- p1 org)) scl))
     )
   (mapcar (function (lambda (x1 x2) (+ (* scl (- x1 x2)) x1)))
    p1
    p2
   )
 )
)

;;; DivSeg (gile)
;;; Retourne la liste des points qui divisent le segment p1 p2 en n segments
;;;
;;; Arguments
;;; p1 p2 : extrémités du segment (points)
;;; n : nombre de divisions (entier positif)

(defun DivSeg (p1 p2 n / v l)
 (setq	v (mapcar (function (lambda (x1 x2) (/ (- x2 x1) n))) p1 p2)
l (cons p2 l)
 )
 (while (    (setq l
   (cons
     (mapcar (function (lambda (x1 x2) (+ x1 (* x2 n)))) p1 v)
     l
   )
   )
 )
 (cons p1 l)
) 

 

[Edité le 27/9/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Invité ingoenius
Posté(e)

WOW je vais tester cela lundi, tu est trés fort je vois merci,

oui tu avaus bien compris le but de la routine, utile sourtout quant justement la projection n'est pas perpendiculaire, donc on peut aisement voir la deformation de la grille projectée de bias

 

demain je teste

;-)

Invité ingoenius
Posté(e)

@Gile

Je vien de tester la routin qui est GENIAL , et que jamais j'aurais pu faire tout seul,

comme tu disais avec l'axe de projection perpendiculaire au batiment ca marche tous seul, mais j'ai testé avec un axe decalé, et le scipt il as pas demandé les point supplementaire pour definir la face3d sur laquelle projecter, et il a fait comme si rien n'etait. (donc tou droit )

 

Il faut ajouter quoi pour faire en sorte que en dans tout les cas possibles le script demande

centre de projection

position projecteur

optique

ratio 16/9 et

 

clik sur 3 point de la face sur laquelle projecter ?

 

merci pour l'aide

Posté(e)

Salut,

 

Le LISP ci dessus, ne fonctionne que si le projecteur est incliné uniquement verticalement.

 

En voici un autre qui fonctionne quelle que soit la position du projecteur par rapport à l'écran.

 

Demo

 

;;; Project (gile)
;;; Dessine la grille d'un projecteur sur un plan non orthogonal.

(defun c:project (/	 target	scr1   scr2   source ratio  aspect
	  height width	ang-h  norm   ang_v  aper_h aper_v
	  v1	 v2	v3     v4     pt1    pt2    pt3
	  pt4
	 )

 ;; Entrées utilisateur
 ;; target : centre de l'image
 ;; scr1 et scr2 : points sur le plan de l'écran
 ;; source : position du projecteur
 ;; ratio : ratio de projection
 ;; aspect : format de l'image

 (initget 1)
 (setq	target (getpoint "\nSpécifiez le centre de l'image: ")
scr1   target
scr2   target
 )
 (while (equal scr1 target)
   (setq
     scr1 (getpoint
     target
     "\nSpécifiez un second point sur le plan de l'écran: "
   )
   )
 )
 (while (or (equal scr2 target) (equal scr2 scr1))
   (setq
     scr2 (getpoint
     target
     "\nSpécifiez un troisième point sur le plan de l'écran: "
   )
   )
 )
 (initget 1)
 (setq
   source (getpoint target "\nSpécifiez la position du projecteur:")
 )
 (initget 1)
 (setq ratio (getreal "\nEntrez le ratio de projection: "))
 (initget 1 "16x9 4x3 5x4")
 (setq
   aspect (getkword "\nEntrez le format de l'image [16x9/4x3/5x4]:")
 )
 (foreach p '(target scr1 scr2 source)
   (set p (trans (eval p) 1 0))
 )

 ;; Calcul des angles
 ;; ang_h : angle horizontal de l'axe de projection / axe X
 ;; ang_v : angle vertical de l'axe de projection / plan XY
 ;; aper_h : demi angle horizontal du faisceau
 ;; aper_v : demi angle vertical du faisceau
 ;; norm : normale du plan de l'écran
 (cond
   ((= aspect "16x9")
    (setq height 9
   width 16
    )
   )
   ((= aspect "4x3")
    (setq height 3
   width 4
    )
   )
   ((= aspect "5x4")
    (setq height 4
   width 5
    )
   )
 )
 (setq	ang_h  (angle source target)
ang_v  (atan (- (caddr target) (caddr source))
	     (distance (list (car target) (cadr target))
		       (list (car source) (cadr source))
	     )
       )
aper_h (atan 0.5 ratio)
aper_v (atan (* height (sin aper_h)) width)
norm   (norm_3pts target scr1 scr2)
 )

 ;; calcul des vecteurs directeurs des arrêtes du faisceau (axe faisceau // axe X)
 (mapcar
   (function
     (lambda (v ah av)
(set v
     (mxv
       (mxm
	 (list (list (cos ah) (- (sin ah)) 0)
	       (list (sin ah) (cos ah) 0)
	       '(0 0 1)
	 )
	 (list (list (cos av) 0 (- (sin av)))
	       '(0 1 0)
	       (list (sin av) 0 (cos av))
	 )
       )
       '(1 0 0)
     )
)
     )
   )
   '(v1 v2 v3 v4)
   (list aper_h aper_h (- aper_h) (- aper_h))
   (list (- aper_v) aper_v aper_v (- aper_v))
 )

 ;; rotations des vecteurs suivant les angles ang_h et ang_v
 (foreach v '(v1 v2 v3 v4)
   (set v
 (mxv
   (mxm
     (list (list (cos ang_h) (- (sin ang_h)) 0)
	   (list (sin ang_h) (cos ang_h) 0)
	   '(0 0 1)
     )
     (list (list (cos ang_v) 0 (- (sin ang_v)))
	   '(0 1 0)
	   (list (sin ang_v) 0 (cos ang_v))
     )
   )
   (eval v)
 )
   )
 )

 ;; calcul des points d'intersection des arrêtes et du plan de projection
 (mapcar
   (function
     (lambda (p v)
(set p (ilp source (mapcar '+ source v) target norm))
     )
   )
   '(pt1 pt2 pt3 pt4)
   (list v1 v2 v3 v4)
 )

 ;; dessin de l'image sur le plan de projection
 (mapcar
   (function
     (lambda (p1 p2)
(entmake (list '(0 . "LINE") (cons 10 p1) (cons 11 p2)))
     )
   )
   (append (DivSeg pt1 pt2 height) (DivSeg pt2 pt3 width))
   (append (DivSeg pt4 pt3 height) (DivSeg pt1 pt4 width))
 )

 ;; dessin des arrêtes du faisceau
 (foreach p (list pt1 pt2 pt3 pt4)
   (entmake (list '(0 . "LINE") (cons 10 source) (cons 11 p)))
 )

 (princ)
)

;; VXV (gile)
;; Retourne le produit scalaire (réel) de deux vecteurs
;;
;; Arguments : deux vecteurs

(defun vxv (v1 v2) (apply '+ (mapcar '* v1 v2)))

;; V^V
;; Retourne le produit vectoriel (vecteur) de deux vecteurs
;;
;; Arguments : deux vecteurs

(defun v^v (v1 v2)
 (list	(- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2)))
(- (* (caddr v1) (car v2)) (* (car v1) (caddr v2)))
(- (* (car v1) (cadr v2)) (* (cadr v1) (car v2)))
 )
)

;; VUNIT
;; Retourne le vecteur unitaire d'un vecteur
;;
;; Argument : un vecteur

(defun vunit (v)
 ((lambda (l)
    (if (/= 0 l)
      (mapcar (function (lambda (x) (/ x l))) v)
    )
  )
   (distance '(0 0 0) v)
 )
)

;; NORM_3PTS (gile)
;; Retourne le vecteur normal du plan défini par 3 points
;;
;; Arguments : trois points

(defun norm_3pts (p0 p1 p2)
 (vunit (v^v (mapcar '- p1 p0) (mapcar '- p2 p0)))
)

;; TRP
;; transpose une matrice -Doug Wilson-
;;
;; Argument : une matrice

(defun trp (m) (apply 'mapcar (cons 'list m)))

;; MXV
;; Applique une matrice de transformation à un vecteur -Vladimir Nesterovsky-
;;
;; Arguments : une matrice et un vecteur

(defun mxv (m v)
 (mapcar (function (lambda (r) (vxv r v))) m)
)

;; MXM
;; Multiple (combine) deux matrices -Vladimir Nesterovsky-
;;
;; Arguments : deux matrices

(defun mxm (m q)
 (mapcar (function (lambda (r) (mxv (trp q) r))) m)
)

;; ILP (gile)
;; Retourne le point d'intersection de la droite définie par p1 p2
;; et du plan défini par un point et sa normale.
;;
;; Arguments
;; p1 et p2 : les points définissant la droite dont on cherche l'intersection
;; org : un point queconque du plan d'intersection
;; nor : le vecteur normal du plan d'intersection

(defun ilp (p1 p2 org nor / scl)
 (if (and
(/= 0 (setq scl (vxv nor (mapcar '- p2 p1))))
(setq scl (/ (vxv nor (mapcar '- p1 org)) scl))
     )
   (mapcar (function (lambda (x1 x2) (+ (* scl (- x1 x2)) x1)))
    p1
    p2
   )
 )
)

;;; DivSeg (gile)
;;; Retourne la liste des points qui divisent le segment p1 p2 en n segments
;;;
;;; Arguments
;;; p1 p2 : extrémités du segment (points)
;;; n : nombre de divisions (entier positif)

(defun DivSeg (p1 p2 n / v l)
 (setq	v (mapcar (function (lambda (x1 x2) (/ (- x2 x1) n))) p1 p2)
l (cons p2 l)
 )
 (while (    (setq l
   (cons
     (mapcar (function (lambda (x1 x2) (+ x1 (* x2 n)))) p1 v)
     l
   )
   )
 )
 (cons p1 l)
) 

 

[Edité le 28/9/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Invité ingoenius
Posté(e)

GRANDE ;-) ça fonctionne a merveille merci Gile encore un fois c'est simple et bien fait .....

 

il faut que j'etudie ça pour comprendre comme tu a fait !

 

pour te remercier j'ai plein de script Python pour blender si ca t'interesse ;-)

(car j'utilisr autocad pour les plans et blender pour les rendu 3d)

 

merci ancore pour tou ca ;-)

 

 

PS

le vrai challenge impossible

 

le rêve inavoué par contre mais ça mémé toi je ne pense pas qui puisse le faire c'est d'indiquer un volume de projection quelconque, solide cylindre etc et récupérer la grille déformée , mais in faudrait que autocad detecte chaque face du volume et que envoi les rayon seulement ou il le faut

 

 

 

 

[Edité le 29/9/2008 par ingoenius]

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité