Aller au contenu

Messages recommandés

Posté(e)

hello

j'ai une fonction qui calcul la distance perpendiculaire d'un point par rapport a 2 autre points

 

 

(defun distperp2d  (point1 point2 point3 / distperp x1 x2 y1 y2 x3 y3)
 ;;calcule la distance du point 3 par rapport a la droite 1 2
 ;;(point1 point2 point3 / x1 x2 x3 y1 y2 y3)

 (setq	x1 (car point1)
y1 (cadr point1)
x2 (car point2)
y2 (cadr point2)
x3 (car point3)
y3 (cadr point3)
) ;_ Fin de setq
 (setq	distperp
 (/
   (abs (- (* (- x3 x1) (- y2 y1)) (* (- y3 y1) (- x2 x1))))
   (sqrt
     (+ (expt (- x2 x1) 2) (expt (- y2 y1) 2))
     ) ;_ Fin de sqrt
   ) ;_ Fin de /
) ;_ Fin de setq
 distperp
 ) ;_ Fin de defun

 

 

cette fonction ne marche qu'en 2d

mais je n'arrive pas a faire la même en 3d avec z1 z2 z3

bon courage, parce que moi je galéré.

Vous fîtes ce que vous pûtes

et vous m'épatâtes !!!!

Posté(e)

Salut,

 

Avec un peu de calcul vectoriel :

 

;; Retourne le vecteur de p1 à p2
(defun vect (p1 p2)
 (mapcar '- p2 p1)
)

;; Retourne la norme (longueur) du vecteur v
(defun vlen (v)
 (distance '(0. 0. 0.) v)
)

;; Retourne le produit vectoriel de v1 et v2
(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)))
 )
)

;; Retourne la distance de pt à la droite p1 p2
(defun distper3d (pt p1 p2 / v)
 (/
   (vlen (v^v (vect p1 pt) (vect p1 p2)))
   (distance p1 p2)
 )
)

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

Posté(e)

merci gile

j'avais bidouillé quelque truc avec tes fonction vectorielle

mais les les matrices....

ca me depasse

Vous fîtes ce que vous pûtes

et vous m'épatâtes !!!!

Posté(e)

Salut,

 

Un segment de droite, et un point forme un plan, sert toi de la géométrie plane notamment de la résolution des trigones, si tu n’es pas à l’aise avec le calcul vectoriel.

 

Avec le théorème d'Al-Kashi qui donne :

b² = a² + c² - 2ac cos (alpha)

 

Et sachant que :

1 = cos (alpha)² + sin (alpha)²

 

On peut en déduire la fonction Lisp suivante :

;;Retourne la distance du point C par rapport a la droite A B
(defun distper3d (A B C)
 ((lambda (a b c) (* b (sqrt (- 1 (expt (/ (- (+ (* b b ) (* c c)) (* a a)) (* 2 b c)) 2)))))
   (distance B C)
   (distance C A)
   (distance A B)
 )
)

Ou A, B, C sont respectivement tes points 1, 2, 3 par soucis de correspondance avec les notations mathématiques courantes.

 

 

Rq:(gile) c’est étrange nos expressions ne donnent pas les mêmes résultats dans l’espace, j’ai testé graphiquement la mienne semble correcte… Ou alors j'ai loupé un truc..

 

A+

Apprendre => Prendre => Rendre

Posté(e)

Rq:(gile) c’est étrange nos expressions ne donnent pas les mêmes résultats dans l’espace, j’ai testé graphiquement la mienne semble correcte… Ou alors j'ai loupé un truc..

 

Non, nos résultats sont identiques, c'est l'ordre des arguments qui est différent.

J'ai mis 'pt' (le point) avant 'p1' et 'p2' (la droite) et tu a mis 'a' et 'b' (la droite) avant 'c' (le point).

 

PS: joli coup avec Al Kashi

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

Posté(e)

Non, nos résultats sont identiques, c'est l'ordre des arguments qui est différent.

J'ai mis 'pt' (le point) avant 'p1' et 'p2' (la droite) et tu a mis 'a' et 'b' (la droite) avant 'c' (le point).

Ok je comprends mieux..

 

PS: joli coup avec Al Kashi

Merci, pour la petite histoire c’est que tout récemment que je viens de redécouvrir (voir même découvrir dans certain cas) la résolution des trigones et tous les bénéfices que l’on peut en tirer.

 

A+

Apprendre => Prendre => Rendre

  • 2 semaines après...
Posté(e)

Merci a vous

j'ai testé les deux fonctions.

elles marchent bien!

mon prog marche bien.

 

 

merci pour la leçon

merci a monsieur al-kashi et vectorielle .....

Vous fîtes ce que vous pûtes

et vous m'épatâtes !!!!

Posté(e)

merci a monsieur al-kashi et vectorielle .....

 

L’important était de voir que l’on pouvait formaliser ton énoncé du problème de la façon suivant :

Soit un triangle A, B, et C. Exprimez la hauteur h issue de C connaissant les coordonnées de ses sommets.

 

Maintenant sachant cela, on peut facilement allonger la liste des remerciements avec par exemple Héron d'Alexandrie en passant par le calcul de l’aire d’un triangle en fonction de ses 3 cotés. La formule de Héron nous donne :

A = racine carré de (p (p – a)(p – b )(p – c)) avec le demi-périmètre p = (a+b+c)/2

 

Et sachant que l’aire d’un triangle A = (Hauteur x Largeur) / 2

 

On en déduit la fonction Lisp suivante (un poil plus rapide que la précédente) :

;; Hauteur issue de C dans le triangle ABC
(defun HauteurC (A B C)
 ((lambda (a b c / p)
    (setq p (/ (+ a b c) 2)) ; demi perimetre
    (/ (* 2 (sqrt (* p (- p a) (- p b ) (- p c)))) c)
  )
   (distance B C)
   (distance C A)
   (distance A B)
 )
)

 

A+

Apprendre => Prendre => Rendre

Posté(e)

bonjour

c'est exactement ce que je voulais faire

calculer la surface d'une face3D, chose que ne fait pas autocad

voila le prog

 

(defun c:surf3d	 ()
 (setq sel (ssget '((0 . "3DFACE"))))
 (setq	cpt 0
listface nil
surf3d nil
cumulsurf3d 0
surf2d nil
cumulsurf2d 0
)
 (repeat (sslength sel)
   (setq ent	   (entget (ssname sel cpt))
  listface nil
  listface (cons (cdr (assoc 10 ent)) listface)
  listface (cons (cdr (assoc 11 ent)) listface)
  listface (cons (cdr (assoc 12 ent)) listface)
  listface (cons (cdr (assoc 13 ent)) listface)


  )
   (setq listface (remove_doubles listface))
   (if	(= (length listface) 3)
     (progn
     (setq surf3d
     (/
       (*
	 (distance (nth 0 listface) (nth 1 listface))
	 (distper3d (nth 2 listface)
		    (nth 0 listface)
		    (nth 1 listface)
		    )
	 )
       2
       )
    )
(setq surf2d
     (/
       (*
	 (distance
	   (list (car(nth 0 listface))(cadr(nth 0 listface)))
	   (list (car(nth 1 listface))(cadr(nth 1 listface)))
	   )
	 (distper3d (list (car(nth 2 listface))(cadr(nth 2 listface))0.0)
		    (list (car(nth 0 listface))(cadr(nth 0 listface))0.0)
		    (list (car(nth 1 listface))(cadr(nth 1 listface))0.0)
		    )
	 )
       2
       )
    )


     
     )
     (alert "FACE3D a 4 sommets Calcul impossible")
     )
   (setq cumulsurf3d (+ cumulsurf3d surf3d))
   (setq cumulsurf2d (+ cumulsurf2d surf2d))
   (setq cpt (+ cpt 1))
   )



 ;; Retourne le vecteur de p1 à p2
 (defun vect  (p1 p2)
   (mapcar '- p2 p1)
   )

 ;; Retourne la norme (longueur) du vecteur v
 (defun vlen  (v)
   (distance '(0. 0. 0.) v)
   )

 ;; Retourne le produit vectoriel de v1 et v2
 (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)))
     )
   )

 ;; Retourne la distance de pt à la droite p1 p2
 (defun distper3d  (pt p1 p2 / v)
   (/
     (vlen (v^v (vect p1 pt) (vect p1 p2)))
     (distance p1 p2)
     )
   )

(defun remove-i (ind lst)
 (if (or (zerop ind) (null lst))
   (cdr lst)
   (cons (car lst) (remove-i (1- ind) (cdr lst)))
 )
)
(defun remove_doubles (lst)
 (if lst
   (cons (car lst) (remove_doubles (vl-remove (car lst) lst)))
 )
)
 )

Vous fîtes ce que vous pûtes

et vous m'épatâtes !!!!

Posté(e) (modifié)

Bonjour,

 

Pour trouver l'aire de faces 3D, j'avais dans ce sujet utilisé la formule de Kahan, une variante de la formule de Héron:

 

(defun bs:triangleArea ( coords / longueurs a b c )
; Argument : une liste de 3 points, chaque point étant une liste de 2 ou 3 coordonnées
; Retour : la surface du triangle (nombre réel)

 (setq longueurs (cons (distance (car coords) (cadr coords)) longueurs)
       longueurs (cons (distance (cadr coords) (caddr coords)) longueurs)
       longueurs (cons (distance (caddr coords) (car coords)) longueurs)
       longueurs (bs:sort longueurs '>); tri décroissant
 )
 (apply '(lambda (a b c) (/ (sqrt (* (+ a b c) (- c (- a B)) (+ c (- a B)) (+ a (- b c)) ) ) 4.0)) longueurs)
)

(defun bs:sort ( l fun / )
; fonctionne comme vl-sort, mais sans supprimer les doublons de la liste
 (mapcar '(lambda (x) (nth x l)) (vl-sort-i l fun))
)

(defun c:3DFAREA ( / ss i f aire )
 (setq ss (ssget '((0 . "3DFACE"))))
 (if ss
   (progn
     (setq i 0
           aire 0.0)
     (repeat (sslength ss)
       (setq f (entget (ssname ss i))
             aire (+ aire (bs:triangleArea (list (cdr (assoc 10 f)) (cdr (assoc 11 f)) (cdr (assoc 12 f)))))
             i (1+ i))
     );repeat
     (prompt (strcat "\n" (itoa i) " faces 3D traitées, aire totale : " (rtos aire 2 8)))
   );progn
 );if
 (princ)
)

 

Edit: c'est bizarre, il y a des B qui se remettent systématiquement en majuscules dans la fonction lambda ?! :mellow:

Modifié par bryce
Posté(e)

Edit: c'est bizarre, il y a des B qui se remettent systématiquement en majuscules dans la fonction lambda ?! :mellow:

 

Avec un espace après le b cela passe..

(apply '(lambda (a b c) (/ (sqrt (* (+ a b c) (- c (- a b )) (+ c (- a b )) (+ a (- b c)) ) ) 4.0))

 

A+

Apprendre => Prendre => Rendre

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é