(gile) Posté(e) le 12 avril 2009 Posté(e) le 12 avril 2009 Salut, tu utilises le même index pour parcourir le jeu de sélection (ssname) et pour numéroter tes objets. il faut un index pour parcourir la sélection (ind) et un d'autres pour chaque type d'entité à numéroter (indA, indL, indPO, indSP ...) ((= typ "LINE") (setq ent (ssname selset ind) ind (1+ ind) indL (1+ indL)) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
willy95 Posté(e) le 12 avril 2009 Auteur Posté(e) le 12 avril 2009 Salut, En fait j'ai beau tout essayé je ne comprends pas vraiment , En fait, je crois que je recherche le nom de la premiere entité qui se nomme : "npt" dans le jeu deselection indSL, car actuellement je recupere le nom de la derniere entité : Il existe pas une fonction ou une formule mathématique pour cela ? :( Voila ce que sa donne : ( le 9 est pas bon ) 1:X=4649.8419,Y=2189.5361 2:X=3973.0397,Y=2185.9965 3: 8:X=1265.831,Y=2147.0609 9:X=1074.4838,Y=2147.0609 ARC N°1 du point [u] 9 [/u] au point 9 :D Alors que je souhaite : (le 1 est bon ) 1:X=4649.8419,Y=2189.5361 2:X=3973.0397,Y=2185.9965 3: 8:X=1265.831,Y=2147.0609 9:X=1074.4838,Y=2147.0609 ARC N°1 du point [u] 1 [/u] au point 9 ;) Comment dois-je faire ? Merci
(gile) Posté(e) le 12 avril 2009 Posté(e) le 12 avril 2009 Je ne suis pas sûr de comprendre ce que tu veux faire.Dans tous les cas, il faut bien comprendre que tu utilises plusieurs indices incrémentés :- ind = indice des entités dans le jeu de sélection à utiliser avec ssname (+1 à chaque nouvelle entité)- npt = indice des points (+1 à chaque point indépendamment des entités)- indA, indL, indPO, indSP = indices des entités par type (+1 à chaque nouvelle entité suivant son type) Si, j'ai bien compris tu veux générer 2 fichiers :- un contenant uniquement les points et leurs indices (file1)- un autre contenant les types d'entités numérotés avec les indices des points correspondants (file2) Pour les polylignes par exemple (je te laisse transposer pour les autres entités), on peut faire : ((= typ "LWPOLYLINE") ;; incrémenter le numéro de polyligne et récupérer l'indice du premier point (setq indPO (1+ indPO) str (strcat "Polyligne N°" (itoa indPO) " du point " (itoa (1+ npt)))) ;; écrire tous les points dans file1 (foreach p (massoc 10 dxflst) (setq npt (1+ npt)) (write-line (strcat (itoa npt) ":X=" (rtos (cadr p)) ",Y=" (rtos (caddr p)) ) file1 ) ) ;; écrire la ligne dans file 2 après avoir récupéré l'indice du dernier point (write-line (strcat str " au point " (itoa npt)) file2) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 12 avril 2009 Posté(e) le 12 avril 2009 coucou je suis ce post depuis le début il se trouve que je ne comprends pas non plus où veux tu en venir ? c'est pour faire un format VPMNT ? spécifique à la SNCF amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
willy95 Posté(e) le 12 avril 2009 Auteur Posté(e) le 12 avril 2009 Voila je souhaite ressortir a la fin de chaque splineun résumé qui dit :Spline n°1 (itoa indSP)débute au point n° : ( itoa ?????)et fini au point n° ( itoa ?????)Mon probleme actuel est que j'obtient seulement le dernier point de la splinenormale puisque j'ai ecris : (itoa npt)au lieu du 1er point . Je souhaite ecrire tous dans le meme fichiermais sur plusieurs lignes, genre : 1:X=4649.8419,Y=2189.5361 2:X=3973.0397,Y=2185.9965 3: 8:X=1265.831,Y=2147.0609 9:X=1074.4838,Y=2147.0609 ARC N°1 du point 1 au point 9 Je ne sais pas comment obtenir le n° du premier point ? ((= typ "SPLINE") (setq ent (ssname selset indSP) indSP (1+ indSP)) (foreach p (massoc 11 dxflst) (setq npt (1+ npt)) (write-line (strcat (itoa npt) ":X=" (rtos (cadr p)) ",Y=" (rtos (caddr p))) file)) (write-line (strcat "N°Spline:" (itoa indSP) "N° du 1er Point :" (itoa ??????????? )) ) file) file))
(gile) Posté(e) le 12 avril 2009 Posté(e) le 12 avril 2009 Regarde ma dernière réponse (N° 27) il suffit de remplacer file1 et file2 par file. On récupère l'indice du premier point de la polyligne (ou la spline) avant de commencer le traitement de la polyligne (et l'incrémentation de npt). On peut stocker cette valeur directement dans la chaîne qui sera écrite dans le fichier après le traitement de la polyligne. (setq indPO (1+ indPO) str (strcat "Polyligne N°" (itoa indPO) " du point " (itoa (1+ npt)))) qui retourne (par exemple si npt = 15 soit l'indice du dernier point de l'entité précédente) :"Polyligne N°3 du point 16" Ensuite on traite la polyligne et donc on incrémente npt (par exemple 12 points). On peut alors connaitre l'indice du dernier point de la polyligne, soit npt = 28 et écrire la ligne dans le fichier : (write-line (strcat str " au point " (itoa npt)) file) soit : "Polyligne N°3 du point 16 au point 28" Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
willy95 Posté(e) le 13 avril 2009 Auteur Posté(e) le 13 avril 2009 Encore MErciJ'ai eu du mal a comprendre l'enregistrementde la variable "npt" dans la variable "str".Mais grace a cela j'ai appris plein de chosescomme "file1" et "file2" et beaucoup d'autres... Maintenant j'ai bien mon souhait :Spline n°3 ,Pt de départ n°16 et le pt d'arrivé n°23. Et pour finir je me suis battu presque toute la nuitsans obtenir de résultat pour ecrire une ligne aprèsqui résume les points intérmédiaires sachant qued'une spline a l'autre il n'y a pas le meme nombre de pts. genre : Passant par les point n° : 17,18,19,20,21,22 Cela cloturai ce code, il ne me resterai qu'a reproduire ce cas aux autres entité du genre. Après cette nuit fastidieuse j'espere beaucoupobtenir une aide délivrante. Merci d'avance pour votre aide.
(gile) Posté(e) le 13 avril 2009 Posté(e) le 13 avril 2009 Salut, Là je ne comprends plus ce que tu veux faire !Si le point de départ de la spline est le numéro16 et le point de fin le numéro 23, elle passe obligatoirement par les points 17, 18, 19, 20, 21 et 22. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
willy95 Posté(e) le 13 avril 2009 Auteur Posté(e) le 13 avril 2009 Je souhaite seulement ecrire une ligne suplementairequi donne les numeros des points intermédiairesJ'ai besoin qu'il soient marqué malgrès que c'est évident.
(gile) Posté(e) le 13 avril 2009 Posté(e) le 13 avril 2009 ((= typ "SLINE") ; idem pour LWPOLYLINE ;; incrémenter le numéro de polyligne et récupérer l'indice du premier point (setq indPO (1+ indPO) start (1+ npt) str1 (strcat "Spline N°" (itoa indPO) " du point " (itoa start) ) str2 "Passant par les points N° : " ) ;; écrire tous les points (foreach p (massoc 10 dxflst) (setq npt (1+ npt)) (write-line (strcat (itoa npt) ":X=" (rtos (cadr p)) ",Y=" (rtos (caddr p)) ) file ) ) ;; écrire la ligne après avoir récupéré l'indice du dernier point (write-line (strcat str1 " au point " (itoa npt)) file) ;; écrire la ligne "Passant par ..." (while ( (setq str2 (strcat str2 (itoa start) ", ")) ) (write-line (strcat str2 (itoa (1- npt))) file) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
willy95 Posté(e) le 13 avril 2009 Auteur Posté(e) le 13 avril 2009 Salut, Tout d'abord Merci pour ce temps passé a mon egart. Je suis presque a la fin mais...Je ne comprend pas pourquoi le codefonctionne bien avec la spline et pas avec les polylignes !!Des que je suprime le passage polyligne il y a aucun problemeet des qu'il est la :Il me marque :" erreur: parenthèse fermante supplémentaire en entrée "et quand je selectionne une polyligne il manque dans le fichierles points !?donc je suppose que cela se passe dans les : " file ))" pouvez vous m'aider il y a quelque chose qui n'est pas bonmais ou , la est mon probleme. Comme a mon habitude j'ai retourné le probleme danstous les sens, merci d'avance pour votre aide. Voici une partie du code ! ((= typ "CIRCLE") (setq ent (ssname selset indC) indC (1+ indC)) ;(write-line (strcat (itoa indC) " Cercle") file) (setq pt (cdr (assoc 10 dxflst)) npt (1+ npt)) (write-line (strcat (itoa npt) ":X=" (rtos (car pt)) ",Y=" (rtos (cadr pt)) (strcat model) ) file)) ;;-------------------------------------------------------------------------- ((= typ "LWPOLYLINE") (setq str (1+ npt)) (setq start (1+ npt) str1 (strcat "" (itoa start)) str2 "" ) (setq ent (ssname selset indSP) indSP (1+ indPO)) (foreach p (massoc 11 dxflst) (setq npt (1+ npt)) (write-line (strcat (itoa npt) ":X=" (rtos (cadr p)) ",Y=" (rtos (caddr p)) (strcat model)) file)) (write-line (strcat "Abod." (itoa indPO) ":MD=EPA_313") file) (write-line (strcat "Abod." (itoa indPO) "&D0:") file) ;(write-line (strcat str1 " au point " (itoa npt)) file) (strcat str1 " au point " (itoa npt)) (while (< (setq start (1+ start)) (1- npt)) (setq str2 (strcat str2 (itoa start) "*"))) ;(write-line (strcat str2 (itoa (1- npt))) file) (strcat str2 (itoa (1- npt))) (write-line (strcat "Abod." (itoa indPO) "&L0:*" str1 "*" str2 (itoa (1- npt)) ) file) (write-line (strcat "Abod." (itoa indPO) "&L1:/" (itoa npt) ) file) (write-line (strcat "Abod." (itoa indPO) "&V1:Meth=MdMoL") file) file)) ;;-------------------------------------------------------------------------- ((= typ "SPLINE") (setq str (1+ npt)) ;(setq indSP (1+ indSP) (setq start (1+ npt) str1 (strcat "" (itoa start)) str2 "" ) (setq ent (ssname selset indSP) indSP (1+ indSP)) ;(write-line (strcat (itoa ind) " Spline") file) ;pour tous les points de lissage de la spline (foreach p (massoc 11 dxflst) (setq npt (1+ npt)) (write-line (strcat (itoa npt) ":X=" (rtos (cadr p)) ",Y=" (rtos (caddr p)) (strcat model)) file)) (write-line (strcat "Abod." (itoa indSP) ":MD=EPA_313") file) (write-line (strcat "Abod." (itoa indSP) "&D0:") file) ;(write-line (strcat str1 " au point " (itoa npt)) file) (strcat str1 " au point " (itoa npt)) (while (< (setq start (1+ start)) (1- npt)) (setq str2 (strcat str2 (itoa start) "*"))) ;(write-line (strcat str2 (itoa (1- npt))) file) (strcat str2 (itoa (1- npt))) (write-line (strcat "Abod." (itoa indSP) "&L0:*" str1 "*" str2 (itoa (1- npt)) ) file) (write-line (strcat "Abod." (itoa indSP) "&L1:/" (itoa npt) ) file) (write-line (strcat "Abod." (itoa indSP) "&V1:Meth=MdMoL") file) file)) ;;-------------------------------------------------------------------------- ;fin de cond ) ;fin de while (close file) ;fermeture du fichier ) ;fin de progn ) ;fin de if ) ;fin de if (princ) )
(gile) Posté(e) le 14 avril 2009 Posté(e) le 14 avril 2009 Salut, J'aurais du commencer par là : je te conseille d'utiliser l'éditeur Visual LISP (ou un autre éditeur de code) qui facilite l'appariement des parenthèses et la lecture du code en le formatant. D'après ce que je vois de l'extrait que tu donnes, supprime file) à la fin des listes cond pour la spline et la polyligne. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
willy95 Posté(e) le 14 avril 2009 Auteur Posté(e) le 14 avril 2009 Bonjour à tous... Tout d'abord je tiens à remercier "Gile" particulièrement pour toute l'aidequ'il ma apportée, l'enseignement et l'autoréflection qui mes parfoisdouloureuse mais très intellectuellement utile.Et grace à ce forum très instructif et à tous ces intervenants j'évolue,je crois dans le bon sens, MERCI à TOUS... Pour le moment j'ai compris en partie mon avant dernier probleme : Je ne comprend pas pourquoi le codefonctionne bien avec la spline et pas avec les polylignes !! En fait au lieu de : (foreach p (massoc 11 dxflst) pour la spline; Il fallait : (foreach p (massoc 10 dxflst) d'ou ma partie non comprise : pourquoi massoc 10 et 11 ? A part cela les problemes de parentheses sont réglés. En revanche j'ai trouvé encore un hic : Pour mes Polylignes je souhaite obtenir un résultat différent, du genre : * (1°pt) % (2°pt) * (3°pt) % (4°pt) / (5°pt) en clair : Poly.1: *1%2*3%4/5 Je pense que c'est au niveau du while : (while (< (setq start (1+ start)) (1- npt)) (setq str2 (strcat str2 (itoa start) "*"))) Peu etre faut-il créer une variable str3 ? Apres avoir chercher je souhaiterai encore un coup de pouce sur ce coup la.Merci par avance..
(gile) Posté(e) le 14 avril 2009 Posté(e) le 14 avril 2009 pourquoi massoc 10 et 11 ? La fonction massoc (definie dans la routine donnée message N° 9) ressemble à la fonction prédéfinie assoc à ceci près que assoc ne retourne que la première sous liste (ou paire pointée) de la liste passée en second argument dont le premier élément correspond au premier argument, alors que massoc retourne une liste de toutes les sous listes (ou paires pointées) dont le premier élément correspond au premier argument. Regarde dans l'Aide aux développeurs >> AutoLISP Reference >> AutoLISP Functions >> A Functions >> assoc (en anglais) ou ici (en français). (massoc 11 dxflst) récupère toutes les paires pointées dont le code de groupe est 11 (points de lissage) dans la liste des données DXF de la spline.(massoc 10 dxflst) récupère toutes les paires pointées dont le code de groupe est 10 (points de contrôle) dans la liste des données DXF de la spline. Regarde dans l'Aide aux développeurs >> Réfernces DXF >> Section ENTITIES >> Spline (en français pour une fois) Pour ta demande concernant les polylignes je ne comprends pas bien dans quelle ligne tu veux cette syntaxe.Et si tu veux apprendre, tu as maintenant tous les éléments pour le faire. Si tu veux un code tout fait, dis plutôt exactement ce que tu veux écrire dans le fichier pour chaque type d'entité, mais ce n'est pas en se faisant donner des poissons qu'on apprend à pêcher... Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
willy95 Posté(e) le 17 avril 2009 Auteur Posté(e) le 17 avril 2009 Voila c'est pas au point mais ca fonctionne pourles lignes, les polylignes, les arcs,un jour peu etre pour les splines,et peu etre qu'aussi une amélioration pour les points avec descoordonées identique seront suprimés automatiquement.Merci Beaucoup pour tout. Pour ceux que sa intéresse : (defun c:Coo (/ selset filename file ind indA indC indL indPO indSP npt ent ent2 dxflst typ pt xpt1 xpt2 pt4 pt5 angl1 start str str1 str2 ) (setvar "LUNITS" 2) ;Metrique (setvar "LUPREC" 4) ;2 décimales (setvar "AUNITS" 2) ;Grade (setvar "AUPREC" 4) ;4 décimales (setvar "ANGBASE" (/ pi 2)) ;Le zéro au nord (setvar "ANGDIR" 1) ;Sens horaire ;;sélection des entités;; (if (setq selset (ssget '((0 . "ARC,CIRCLE,LINE,LWPOLYLINE,SPLINE")))) ;;création du fichier (if (setq filename (getfiled "Créer un fichier texte" "" "txt" 1)) (progn (setq file (open filename "w") ; ouverture en écriture numpt 0 ; initialisation de l'indice des points ind 0 ; initialisation de l'indice des Entités indA 0 ; initialisation de l'indice pour Arc indC 0 ; initialisation de l'indice pour Cercle indL 0 ; initialisation de l'indice pour Ligne indPO 0 ; initialisation de l'indice pour Polyligne indSP 0 ; initialisation de l'indice pour Spline npt 0 ; initialisation des numéros de points start 0 ; initialisation du point départ str1 0 ; initialisation des points intermédiaire str2 0 ; initialisation du point de fin str3 0 ; initialisation du point str 0 ; initialisation des points xpt1 0 ; initialisation du point 1 intermédiaire xpt2 0 ; initialisation du point 2 intermédiaire ) (setq model (strcat "," "MD=TOPO_POINT_MAT_Z")) ;;Modele Point 1 ;(setq model (strcat "," "MD=JT_PNT_MZ_BD")) ;;Modele Point 2 (setq modeli (strcat "," "MD=CLASSIQUE")) ;;Modele Ligne (setq numpt (strcat "R.")) ;; boucle tant qu'il y a des entités dans le jeu de sélection (while (setq ent (ssname selset ind)) (setq dxflst (entget ent) ; liste des données DXF typ (cdr (assoc 0 dxflst)) ; type d'entité ind (1+ ind) ; incrémentation de l'indice ) ;; traitement suivant le type d'entité (cond ;;-------------------------------------------------------------------------- ((= typ "ARC") (setq ent (ssname selset indA) indA (1+ indA)) ;(write-line (strcat " Arc") file); indice et type d'entité (setq cen (cdr (assoc 10 dxflst))) ; centre (setq rad (cdr (assoc 40 dxflst))) ; rayon (setq ang1 (cdr (assoc 50 dxflst))) ; angle départ (setq ang2 (cdr (assoc 51 dxflst))) ; angle fin (setq start (polar cen ang1 rad)npt (1+ npt)) (write-line (strcat numpt (itoa npt) ":X=" (rtos (car start)) ",Y=" (rtos (cadr start)) (strcat model) )file) (setq mid (polar cen (/ (+ ang1 ang2) 2.0) rad)npt (1+ npt)) (write-line (strcat numpt (itoa npt) ":X=" (rtos (car mid)) ",Y=" (rtos (cadr mid)) (strcat model) )file) (setq end (polar cen ang2 rad)npt (1+ npt)) (write-line (strcat numpt (itoa npt) ":X=" (rtos (car end)) ",Y=" (rtos (cadr end)) (strcat model) )file) (write-line (strcat "Arc." (itoa indA) ":MD=CLASSIQUE") file) (write-line (strcat "Arc." (itoa indA) "&D0:" ) file) (write-line (strcat "Arc." (itoa indA) "&L0:*R." (itoa npt) "&R." (itoa (- npt 1)) "/R." (itoa (- npt 2))) file) (write-line (strcat "Arc." (itoa indA) "&V1:Meth=MdMoL") file) ) ;;-------------------------------------------------------------------------- ((= typ "CIRCLE") (setq ent (ssname selset indC) indC (1+ indC)) ;(write-line (strcat (itoa indC) " Cercle") file) (setq pt (cdr (assoc 10 dxflst)) npt (1+ npt)) (write-line (strcat numpt (itoa npt) ":X=" (rtos (car pt)) ",Y=" (rtos (cadr pt)) (strcat model) ) file)) ;;-------------------------------------------------------------------------- ((= typ "LINE") (setq ent (ssname selset indL) indL (1+ indL)) ;(write-line (strcat (itoa ind) " Ligne") file) (setq pt (cdr (assoc 10 dxflst)) npt (1+ npt)) (write-line (strcat numpt (itoa npt) ":X=" (rtos (car pt)) ",Y=" (rtos (cadr pt)) (strcat model) )file) (setq xpt1 (car pt)) (setq ypt1 (cadr pt)) (setq pt (cdr (assoc 11 dxflst)) npt (1+ npt)) (write-line (strcat numpt (itoa npt) ":X=" (rtos (car pt)) ",Y=" (rtos (cadr pt)) (strcat model) )file) (setq xpt2 (car pt)) (setq ypt2 (cadr pt)) (setq xpt3 (/ (+ xpt1 xpt2)2)) (setq ypt3 (/ (+ ypt1 ypt2)2)) (setq pt4 (list xpt1 ypt1)) (setq pt5 (list xpt2 ypt2)) (setq angl1 (angle pt4 pt5)) (write-line (strcat "Ligne." (itoa indL) ":X=" (rtos xpt3) ",Y=" (rtos ypt3) ",G="(vl-string-right-trim "g" (angtos angl1 2 4)) (strcat modeli)) file) (write-line (strcat "Ligne." (itoa indL)"&L0:*R." (itoa npt) "/R." (itoa (1- npt)) ) file)) ;;-------------------------------------------------------------------------- ((= typ "LWPOLYLINE") (setq str (1+ npt)) (setq start (1+ npt) str1 (strcat "" (itoa start)) str2 "" ) (setq ent (ssname selset indPO) indPO (1+ indPO)) (foreach p (massoc 10 dxflst) (setq npt (1+ npt)) (write-line (strcat numpt (itoa npt) ":X=" (rtos (cadr p)) ",Y=" (rtos (caddr p)) (strcat model)) file)) (write-line (strcat "Poly." (itoa indPO) ":MD=JT_LIN_L_LG") file) (strcat str1 " au point " (itoa npt)) (while (< (setq start (1+ start)) (1- npt)) (setq str2 (strcat str2 (itoa start) "*R."))) ;;(write-line (strcat str2 (itoa (1- npt))) file) (strcat str2 (itoa (1- npt))) (write-line (strcat "Poly." (itoa indPO) "&L0:*" numpt str1 "*" numpt str2 (itoa (1- npt)) "/" numpt (itoa npt) ) file) ) ;;-------------------------------------------------------------------------- ((= typ "SPLINE") (setq str (1+ npt)) ;(setq indSP (1+ indSP) (setq start (1+ npt) str1 (strcat "" (itoa start)) str2 "" ) (setq ent (ssname selset indSP) indSP (1+ indSP)) ;(write-line (strcat (itoa ind) " Spline") file) ;pour tous les points de lissage de la spline (foreach p (massoc 11 dxflst) (setq npt (1+ npt)) (write-line (strcat numpt (itoa npt) ":X=" (rtos (cadr p)) ",Y=" (rtos (caddr p)) (strcat model)) file)) (write-line (strcat "Spline." (itoa indSP) ":MD=JT_LIN_L_LG") file) (write-line (strcat "Spline." (itoa indSP) "&D0:") file) ;(write-line (strcat str1 " au point " (itoa npt)) file) (strcat str1 " au point " (itoa npt)) (while (< (setq start (1+ start)) (1- npt)) (setq str2 (strcat str2 (itoa start) "%R."))) ;(write-line (strcat str2 (itoa (1- npt))) file) (strcat str2 (itoa (1- npt))) (write-line (strcat "Spline." (itoa indSP) "&L0:*" numpt str1 "*" numpt str2 (itoa (1- npt)) ) file) (write-line (strcat "Spline." (itoa indSP) "&L1:/R." (itoa npt) ) file) ) ;;-------------------------------------------------------------------------- ) ;fin de cond ) ;fin de while (close file) ;fermeture du fichier ) ;fin de progn ) ;fin de if ) ;fin de if (princ) ) ;; MASSOC ;; Retourne la liste de toutes les entrées du ;; code spécifié d'une liste d'association ;; ;; Arguments ;; code : le code de groupe pour les entrées ;; lst : la liste d'association (defun massoc (code lst / ret) (foreach n lst (if (= (car n) code) (setq ret (cons n ret)) ) ) (reverse ret) )
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant