Aller au contenu

Il y a 10 types de personnes dans le monde : celles qui comptent en binaire et les autres


Messages recommandés

Posté(e)

Ce sujet s'adresse aux autres.

Posons d'abord les bases.
AutoLISP utilise des nombres entiers signés codés sur 32 bits. Ça signifie qu'un entier représenté par sa valeur binaire (en base 2) occupe 32 unités binaires (bits), chacune ayant une valeur de 1 ou 0.
Le bit dit "de poids fort" ou bit 31 (le plus à gauche), sert à déterminer le signe : positif si égal à 0 ; négatif si égal à 1.
Les nombres entiers sont donc compris entre -2^31 (-2147483648) et 2^31 - 1 (2147483647).

1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  -2147483648
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1  -2147483647
...
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1           -3
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0           -2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1           -1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0            0  
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1            1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0            2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1            3
...
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0   2147483646
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1   2147483647

Cette représentation des nombres entiers (outre le fait que ce soit celle utilisée à bas niveau par les ordinateurs) permet de faciliter certaines opérations appelées "opérations de bit à bit" (bitwise en anglais), notamment les opérations de logique booléenne.

AuotLISP fournit des fonctions pour ce type d'opérations : ~ (tilde), boole,  logand, logior et lsh que je vais tâcher d'expliquer dans les messages suivants.
 

EDIT : Une discussion récente m'a fait remarqué que j'avais oublié de citer les codes binaires dans certains groupes de code DXF et les filtres de sélection. J'ai donc ajouté un "chapitre".

  • Upvote 1

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

Posté(e)

1. ~ (tilde)

Cette fonction renvoie le "complément à 1" d'un nombre (bitwise NOT). Autrement dit, elle inverse tous les bits (les 0 deviennent 1 et vice-versa) y compris le bit de poids fort, donc le signe.

5       0 0 ... 0 0 1 0 1   (5)
(~ 5)   1 1 ... 1 1 0 1 0  (-6)


L'équivalent arithmétique de : (~ n) serait : (- (* n -1) 1)
On verra comment on peut l'utiliser dans la pratique plus bas.

 

  • Like 1

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

Posté(e)

2. boole

C'est la fonction générale pour toutes les opérations 'bit à bit' (bitwise). Les opérations se font au niveau de chaque bit de même rang des nombres passé en argument.
Le premier argument de la fonction boole est un entier entre 0 et 15 qui représente une des 16 opérations booléennes possible.
Les arguments suivants sont les entiers à traiter 'bit à bit' (avec un seul entier, boole renvoie cet entier quel que soit l'opérateur).

Avec 0 comme opérateur (premier argument) le résultat est toujours 0.

Les opérateurs fondamentaux sont 1, 2, 4 et 8. les autres sont des combinaisons de ceux-ci.
Pour une meilleur visibilité, dans les exemples suivants on ne traitera que deux entiers. S'il y en a plus, boole traite les deux premiers, puis les suivants avec le résultat précédent.

L'opérateur 1 renvoie : 1, quand les bits du premier et du second nombre valent tous les deux 1 ; 0, dans tous les autres cas.
C'est l'opérateur logique AND

                0 1 0 1   (5)
                0 1 1 0   (6)
(boole 1 5 6)   0 1 0 0   (4)

L'opérateur 2 renvoie : 1, si le bit du premier nombre vaut 1 et celui du second vaut 0 ; 0, dans tous les autres cas.

                0 1 0 1   (5)
                0 1 1 0   (6)
(boole 2 5 6)   0 0 0 1   (1)  

L'opérateur 4 renvoie : 1, si le bit du premier nombre vaut 0 et celui du second vaut 1 ; 0, dans tous les autres cas.

                0 1 0 1   (5)
                0 1 1 0   (6)
(boole 4 5 6)   0 0 1 0   (2)

L'opérateur 8 renvoie : 1, quand les bits du premier et du second nombre valent tous les deux 0 ; 0, dans tous les autres cas.
C'est l'opérateur logique NOT appliqué à deux nombres (ou plus).

                0 ... 0 1 0 1   (5)
                0 ... 0 1 1 0   (6)
(boole 8 5 6)   1 ... 1 0 0 0  (-8)

Les autres opérateurs sont des combinaisons de ceux ci dessus, dont les plus utilisés sont :

L'opérateur 6 (combinaison des opérateurs 2 et 4) renvoie : 1, si le bit du premier nombre vaut 1 et celui du second vaut 0 ou si le bit du premier nombre vaut 0 et celui du second vaut 1 ; 0, dans tous les autres cas.
C'est l'opérateur logique XOR (ou exclusif).

                0 1 0 1   (5)
                0 1 1 0   (6)
(boole 6 5 6)   0 0 1 1   (3)

L'opérateur 7 (combinaison des opérateurs 1, 2 et 4) renvoie : 1 si un des bits du premier ou du deuxième nombre vaut 1 ; 0, si les deux bits valent 0.
C'est l'opérateur logique OR (ou inclusif).

                0 1 0 1   (5)
                0 1 1 0   (6)
(boole 7 5 6)   0 1 1 1   (7)

 

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

Posté(e)

3. logand ,logior et exemples pratique

Pour les opérations les plus courantes (AND et OR), AutoLISP fournit des fonctions qui remplacent la fonction boole.

(logand x y) est équivalent à (boole 1 x y)

(logior x y) est équivalent à (boole 7 x y)

Dans la pratique, les codes binaires sont un moyen très efficient pour stocker des états au moyen de drapeaux (flags).
Par exemple, AutoCAD utilise ces codes binaire pour stocker l'état des accrochages aux objet courant dans la variable système OSMODE. Chaque mode d'accrochage correspond à un code binaire (1, 2, 4, 8, ...).
Si les accrochages actifs sont EXTrémité (1), MILieu (2) et INTersection (32), OSMODE vaut (1 + 2 + 32 = 35).
Quand on veut modifier les accrochages, pour en ajouter ou en supprimer un par exemple, on ne peut pas se contenter d'additionner ou de soustraire le code binaire correspondant sans savoir si l'accrochage est déjà actif ou pas.

Si je pense ajouter l'accrochage au MILieu par addition alors qu'il est déjà actif :
(+ 35 2) -> 37 soit 32 + 4 + 1, j'ai en fait désactivé MILieu et activé CENtre

On pourrait tester si un accrochage est actif (code binaire est présent) avant de l'ajouter

(if (= (logand (getvar 'osmode) 2) 0)
  (setvar 'osmode (+ (getvar 'osmode) 2))
)

Mais avec la fonction logior, on peut activer un accrochage sans se soucier de savoir s'il est déjà actif.

(setvar 'osmode (logior (getvar 'osmode) 2))


De même pour désactiver un accrochage, avec logand et l'opérateur ~ (tilde) on n'a pas à se soucier de savoir si l'accrochage est actif ou non.

(setvar 'osmode (logand (getvar 'osmode) (~ 2)))

AutoCAD utilise le code binaire 16384 pour désactiver les accrochages actifs sans avoir à modifier les autres valeurs.
Pour désactiver les accrochages, on ajoute 16384 s'il n'est pas déjà présent, pour les réactiver on supprime ce code binaire.
Avec l'opérateur logique XOR et ce code, on peut basculer entre accrochages actifs et inactifs (ce que fait la touche F3).

(setvar 'osmode (boole 6 (getvar 'osmode) 16384))

 

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

Posté(e)

4. lsh

La fonction lsh sert à décaler une valeur binaire vers la gauche ou vers la droite du nombre de bits spécifié.

Décalage à gauche

5           ... 0 0 0 1 0 1   (5)
(lsh 5 1)   ... 0 0 1 0 1 0  (10)
(lsh 5 3)   ... 1 0 1 0 0 0  (40)

Arithmétiquement parlant, ça consiste à multiplier le nombre par 2^x où x est le nombre de bits de décalage.

Décalage à droite

11           0 0 1 0 1 1  (11)
(lsh 11 -1)  0 0 0 1 0 1   (5)
(lsh 11 -3)  0 0 0 0 0 1   (1)

Arithmétiquement parlant, ça consiste à faire une division entière du nombre par 2^x où x est le nombre de bits de décalage.

Les décalages peuvent servir à convertir les valeurs R, G et B des 'couleurs vraies' en un seul entier (celui utilisé par le groupe DXF 420)

Chaque valeur RGB est comprise ente 0 et 255 soit 8 bits (un octet). En décalant vers la gauche le rouge (R) de 16 bits et le vert (G) de 8 bits, puis en faisant le OR logique de ces valeurs on obtient un entier unique sur 24 bits qui a conservé les 3 valeurs RGB (B du bit 0 au bit 7, G du bit 8 au bit 15 et R du bit 16 au bit 23). Il sera donc possible de faire la conversion inverse toujours avec des décalages.

Conversion de RGB en entier :

(defun rgb2int (r g b)
  (logior (lsh r 16) (lsh g 8) b)
)

Dans l'autre sens, pour le R, il suffit de la décaler de 16 bits vers la droite pour retrouver la valeur, pour les autres, on décale d'abord l'entier vers la gauche de façon à placer les valeurs plus a gauche au delà du bit 31 afin de les éliminer. Puis on décale le résultat vers la droite jusqu'au bit 0.

(defun int2rgb (i)
  (list	(lsh i -16)
	(lsh (lsh i 16) -24)
	(lsh (lsh i 24) -24)
  )
)

Ou, peut-être de manière plus parlante, on fait un AND logique avec 255 et R décalé de 16 bits vers la droite, G décalé de 8 bits vers la droite et B sans décalage.

(defun int2rgb (i)
  (list	(logand 255 (lsh i -16))
	(logand 255 (lsh i -8))
	(logand 255 i)
  )
)

 

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

Posté(e)

Coucou,

Ce sujet est très intéressant (et tombe à pic car je commençais justement à étudier d'un peu plus près les opérations bit à bit et l'écriture binaire. Notamment avec cette gestion du code DXF 420 concernant les couleurs RGB. Je trouve très intéressant l'explication de la variable OSMODE sur l'utilisation des fonctions (logior) et (logand) pour ne pas se soucier de la présence d'un accrochage ou non. Lorsque j'avais étudier la question, j'avais optée pour la solution de décomposer la valeur décimale avec les valeurs 2^n mais en passant par l'écriture binaire, cela fait sens donc merci !

En parlant de code DXF j'avais une question (gile), j'ai remarqué que la transparence elle aussi faisait appel à une valeur décimale directement issue d'une opération bit à bit, et il me semble que tu as brièvement expliqué dans un post que cette valeur décimale correspondait à une valeur comprise entre les bits 24 et 31. J'aimerais comprendre un peu mieux pour quelles raison AutoCAD a besoin de fonctionner avec ces valeurs de bits précises au lieu d'utiliser soit la valeur décimale réelle ou bien des bits inférieurs comme de 0 à 7 ? Je comprends (à peu près) que pour la couleur RGB, cela permet de contenir l'information des 3 couleurs dans une unique valeur numérique et dont le traitement est simple en opération bit à bit, mais si la couleur RGB va du bit 0 au bits 23, pourquoi la transparence (qui n'a rien à voir avec le code DXF de la couleur) devrait commencer au bit 24 ?
Chat me perturbe un peu car je n'arrive pas à comprendre la raison de ceci :3

(defun Transp>Dec (n)

	(lsh (lsh n 32) -32)

)

(defun Dec>Transp (n)

	(lsh n 32)

)

Du coup si je ne dis pas de bêtises, on devrait pouvoir obtenir les valeurs de transparence ainsi, nan ?
 

6 hours ago, (gile) said:

1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0   -2147483648
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1   -2147483647
...
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1                                      -3
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0                                      -2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1                                       -1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0                      0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1                       1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0                       2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1                        3
...
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0                     2147483646
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1                      2147483647

Et ensuite, si je me base sur mes maigres connaissances, on peut trouver la valeur d'un nombre en base 10 avec la formule :
bn x B^n + bn x B^(n-1) + ... + b1 x B^1 + b0 x B^0

Avec bn la valeur du bit à la position n et B la base (en binaire B=2).
Donc par exemple en base 2, le nombre 1010 en binaire vaut : 1 x 2^3 + 0 x 2^2 + 1 x 2^1 + 0 x 2^0 = 8 + 0 + 2 + 0 = 10

Cependant, si je comprend bien, sur l'écriture des nombres entiers en 32 bits, cette règle s'applique lorsque son premier bit vaut 0 mais lorsqu'il vaut 1, doit-on faire un NOT de cette règle (donc que 0 vaut 1 et 1 vaut 0 pour effectuer ce calcul) ? Auquel cas, il faudrait inverser la valeur de chaque bit si le premier vaut 1 si l'on souhaite la convertir en base 10 ?
Je débute encore donc désolée si mes explications sont foireuses, incomplètes voire erronées >w<

Bisous,
Luna

Posté(e)
10 hours ago, Luna said:

il me semble que tu as brièvement expliqué dans un post que cette valeur décimale correspondait à une valeur comprise entre les bits 24 et 31

Je parlais d'autres environnements dans lesquels la couleur et la transparence sont exprimées en ARGB où A est le canal Alpha qui représente la transparence. De la même manière que pour le RGB, ça permet de stocker et de retrouver facilement 4 valeurs dans un seul nombre qu'on écrit le plus souvent en hexadécimal ce qui rend la décomposition entre les 4 canaux immédiatement visible : #80FF0000 est un rouge (R = 255, G = 0 B = 0) avec 50% de transparence (A = 128).

 

10 hours ago, Luna said:

Cependant, si je comprend bien, sur l'écriture des nombres entiers en 32 bits, cette règle s'applique lorsque son premier bit vaut 0 mais lorsqu'il vaut 1, doit-on faire un NOT de cette règle (donc que 0 vaut 1 et 1 vaut 0 pour effectuer ce calcul) ? Auquel cas, il faudrait inverser la valeur de chaque bit si le premier vaut 1 si l'on souhaite la convertir en base 10 ?

La notation montrée dans le premier message, est appelé "notation en complément à 2". Elle est cohérente quand on utilise un nombre de bits déterminé (ici 32). Elle permet que l'addition d'un nombre positif et d'un nombre négatif soit juste parce qu'on ignore les dépassements (au delà du bit 31) 1 + -1 = 0 : 

  0 0 0 0 ... 0 0 0 1
+ 1 1 1 1 ... 1 1 1 1
= 0 0 0 0 ... 0 0 0 0

En résumé, si on veut faire des opérations bit à bit sur les nombres, on utilise les fonctions décrites ci-dessus qui sont prévues pour ça. De ce côté là AutoLISP est aussi bien équipé que les autres langages de programmation. Essayer de transcrire en opérations arithmétiques sur les décimaux certaines des opérations bit à bit relèverait plus du challenge.

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

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

5. Codes binaires dans les listes DXF et filtres de sélection (c'était un oubli, c'est réparé)

AutoCAD utilise aussi les codes binaires pour stocker certaines informations dans des groupes DXF, notamment le groupe 70.

Pour les polylignes "allégées" (LWPOLYLINE), ce groupe 70 stocke la propriété "fermée" (Closed) avec le code binaire 1 ainsi que la "génération de type de ligne" (Plinegen) avec le code binaire 128. On retrouve ces deux codes (à côté de plusieurs autres) pour les objets POLYLINE avec le même type de propriétés. Le code binaire 1 est aussi utilisé avec les objets SPLINE pour la même propriété Closed.

Dans les filtres de sélections on peut utiliser deux opérateurs pour filtrer suivant des codes binaires : "&" et "&=".

Le premier "&" filtrera les objets pour lesquels un AND logique entre la valeur du code de groupe de l'entité et celle du filtre est différente de 0.

'((0 . *POLYLINE) (-4 . "&") (70 . 1))

filtrera tout type de polyligne fermée (allégée, 2d ou 3d) quelle que soit la valeur de la "génération de type de ligne".

Le second "&=" filtrera les objets pour lesquels un AND logique entre la valeur du code de groupe de l'entité et celle du filtre est égale à la valeur du filtre (cet opérateur est équivalent au précédent si le filtre ne contient qu'un code binaire).

'((0 . "POLYLINE") (-4 . "&=") (70 . 9))

filtrera les polylignes 3d (8) fermées (1).

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

Posté(e)

Merci @(gile) je comprends mieux maintenant en effet ! Je me disais bien qu'AutoCAD avait tout de même prévu une solution pour spécifier des valeurs binaires dans la liste de filtre sans passer par une écriture lourde.
Le pire c'est que j'ai lu le cours de LeeMac il y a 1-2 semaines sur la fonction (ssget) et je suis complètement passé à côté de ces opérateurs de comparaison ! >n<

Du coup (je sais je suis lourde) pour filtrer une transparence spécifique, comment doit-on s'y prendre ? J'avais essayé avec un (lsh) de 32 bit mais cela ne fonctionne pas...Donc j'ai essayé de décortiquer le problème depuis l'écriture binaire :

;; if Transparency = DuCalque
;;	-> code DXF 440 (facultatif) non présent

;; if Transparency = DuBloc
;;	-> (440 . 16777216) soit 0001 0000 0000 0000 0000 0000 0000 en notation binaire

;; if Transparency = 0
;;	-> (440 . 33554687) soit 0010 0000 0000 0000 0000 1111 1111 en notation binaire

;; if Transparency = 10
;;	-> (440 . 33554661) soit 0010 0000 0000 0000 0000 1110 0101 en notation binaire

;; if Transparency = 20
;;	-> (440 . 33554636) soit 0010 0000 0000 0000 0000 1100 1100 en notation binaire

;; if Transparency = 30
;;	-> (440 . 33554610) soit 0010 0000 0000 0000 0000 1011 0010 en notation binaire

;; if Transparency = 40
;;	-> (440 . 33554585) soit 0010 0000 0000 0000 0000 1001 1001 en notation binaire

;; if Transparency = 50
;;	-> (440 . 33554559) soit 0010 0000 0000 0000 0000 0111 1111 en notation binaire

;; if Transparency = 60
;;	-> (440 . 33554534) soit 0010 0000 0000 0000 0000 0110 0110 en notation binaire

;; if Transparency = 70
;;	-> (440 . 33554508) soit 0010 0000 0000 0000 0000 0100 1100 en notation binaire

;; if Transparency = 80
;;	-> (440 . 33554483) soit 0010 0000 0000 0000 0000 0011 0011 en notation binaire

;; if Transparency = 90
;;	-> (440 . 33554457) soit 0010 0000 0000 0000 0000 0001 1001 en notation binaire

Donc j'ai bien vu que les bits 8 à 23 sont non-utilisés, du coup je suis partie sur l'hypothèse que l'on peut "ignorer" le(s) bit(s) 24 et 25 en faisant un décalage de 20 vers la gauche, puis vers la droite :
 

;; if Transparency = 0
;;	-> (lsh (lsh 33554687 20) -20) retourne 255
;; et
;; if Transparency = 90
;;	-> (lsh (lsh 33554457 20) -20) retourne 25
;; Autrement dit la plus proche supposition que j'ai pu faire c'est :
;; Notons la valeur de la transparence du code 440 "Tsp"
(defun Dec->Transparency (Tsp)
	(fix (/ (* 100 (- 255 (lsh (lsh Tsp 20) -20))) 255.0))
)
;; Ainsi fait j'obtiens bien les résultats suivants :
;;	(dec->Transparency 33554687) retourne 0
;;	(dec->Transparency 33554661) retourne 10
;;	(dec->Transparency 33554636) retourne 20
;;	(dec->Transparency 33554579) retourne 42
;;	(dec->Transparency 33554483) retourne 80
;;	(dec->Transparency 33554457) retourne 90
;;	(dec->Transparency 16777216) retourne 100 (= DuBloc)
;; Cependant je n'arrive pas à comprendre la présence du bit 25 et 24, ni même quelle est la
;; solution un peu plus "directe" pour la conversion...
;; Car du coup je ne sais pas comment faire l'inverse...étant donné que la fonction (fix) me
;; donne la partie entière du résultat de la division mais en partant de la partie entière,
;; je ne peux pas en déterminer les décimales nécessaires...

Donc même si j'arrive à obtenir un résultat concluant dans un sens, je ne peux pas faire la transposition dans l'autre sens à cause de cette fonction (fix)... As-tu déjà étudier ce code DXF 440 pour pouvoir le comparer à des valeurs connues ou pas du tout ?

Bisous,
Luna

Posté(e)

Bonjour Luna

Je vois qu'on est à peu près au même point sur ce sujet.

Voila mes pirouettes mathématiques

(defun int32->int (int32)
	(fix (/ (- 33554687 int32) 2.55))
)
(defun int->int32 (int)
	(fix (- 33554687 (* int 2.55)))
)

je ne suis même pas sur qu'elles sont valable dans tout les cas.

je cherche encore aussi à comprendre la logique de tout cela.

je pense que je vais aller prendre des cours généraliste sur ce sujet.

Posté(e)

En revanche lorsque la valeur est DuBloc, ta fonction retourne 6579400 ce qui n'est pas l'idéal :3

Je n'avais en effet pas remarqué qu'un pas de 10 pour la transparence correspondait à un pas de 25.5 pour la valeur binaire... Belle remarque !
Il est vrai que le résultat, même si concluant, ne me satisfait pas totalement >n< c'est quelque peu frustrant de ne pas comprendre la logique de cette notation ! Après tout la transparence pourrait parfaitement être spécifiée directement avec sa valeur affichée mais au lieu de cela, il s'agit d'un nombre binaire dont on utilise les bits 25 (ou 24 pour DuBloc) à 1, puis les bits 0 à 7. A quoi servent ces bits non-utilisés ? A quoi sert le bit 24/25 ? Quelle serait la valeur supposée pour "DuCalque" (en couleur DuBloc = 0 et DuCalque = 256 par exemple) ? ...

Il est vrai qu'avoir une formation pourrait éclaircir quelques zones d'ombre vui mais de là à en trouver une qui puisse répondre aussi à des questions propres à AutoCAD, difficile à dire :S

Bisous,
Luna

Posté(e)

Salut, Je ne m'étais jamais penché sur cette question, mais @Luna a fait tout le boulot en décortiquant le code 440.
Si on regarde les notation binaires en terme d'octets, on note que l'octet le plus à gauche contient l'information ByBlock et l'octet le plus à droite la valeur de la transparence (plus exactement de l'opacité avec 255  pour opaque à 100%). On obtient cette valeur de la même façon qu'on obtient la valeur du bleu dans les couleurs RGB en décalant de 24 vers la gauche pour éliminer tous les octets de gauche puis en revenant de 24 bits vers la droite :
(lsh (lsh 33554687 24) -24) renvoie 255 (soit 100% d'opacité ou 0% de transparence).

Donc, pour savoir si on est en ByBlock, on récupère la valeur de l'octet le plus à gauche en le décalant de 24 bits vers la droite :
(lsh 16777216 -24) renvoie 1 pour ByBlock et 2 pour toutes les autres valeurs.

Comme on a vu que la transparence exprime en pourcentage l'inverse de l'opacité, soit la valeur de l'octet de droite sur 255, on peut écrire ta fonction dec_>transprency de cette façon :

(defun dec->transparency (d)
  (if (= 1 (lsh d -24))
    100					; Byblock
    (fix (/ (- 255 (lsh (lsh d 24) -24)) 2.55))
  )
)

et la fonction inverse :

(defun transparency->dec (transp)
  (if (= transp 100)			; ByBlock
    (lsh 1 24)
    (logior (lsh 2 24) (fix (* 2.55 (- 100 transp))))
  )
)

 

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

Posté(e)

C'est tout bonnement magnifique !!! En revanche, la fonction (dec->transparency) peut s'écrire sans le (if) car elle est identique à ma fonction donc 

(fix (/ (- 255 (lsh (lsh 16777216 24) -24)) 2.55)) retourne 100

Donc pas la peine de vérifier l'octet le plus gauche :3
Autrement l'utilisation du (logior) démontre parfaitement que je n'ai pas encore compris son utilisation parfaitement ^^" Mais comme chat, je ne serais plus enquiquinée par ce fameux code DXF 440, donc merci beaucoup à vous deux !

Bisous,
Luna

Posté(e)

Bonjour,

sans vouloir la ramener, il faut simplement faire un AND pour récupérer la valeur de droite, on filtre

(boole 1 16777216 255) =>0

(boole 1 33554687 255) => 255

de même pour dubloc en filtrant avec 33554432

  • Like 1

write a book about what ??

Posté(e)
5 hours ago, lrdb@home said:

Bonjour,

sans vouloir la ramener, il faut simplement faire un AND pour récupérer la valeur de droite, on filtre

(boole 1 16777216 255) =>0

(boole 1 33554687 255) => 255

de même pour dubloc en filtrant avec 33554432

Je ne comprends pas ce que tu veux dire.
Comment tu récupères la valeur de droite dans 33554579 avec AND ?

Après, pour voir si ce n'est pas DuBloc, on peut préférer utiliser : (boole 1 33554432 n) à : (logand 2 (lsh n -24))...

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

Posté(e)

bjr (gille),

Comment tu récupères la valeur de droite dans 33554579 avec AND ?

ça doit renvoyer 147 ?

Je suis nul en Lisp, mais un automaticien fait de la sorte pour récupérer l' octet de droite ( plus rapide que des décalages )

 

 

write a book about what ??

Posté(e)
20 hours ago, Luna said:

C'est tout bonnement magnifique !!! En revanche, la fonction (dec->transparency) peut s'écrire sans le (if) car elle est identique à ma fonction donc 


(fix (/ (- 255 (lsh (lsh 16777216 24) -24)) 2.55)) retourne 100

Donc pas la peine de vérifier l'octet le plus gauche :3

Attention, par programmation on peut mettre 100% de transparence (440 . 33554432) ce qui est différent de ByBlock (440 . 16777216). Dans les deux cas l'octet de droite est à 0.

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

Posté(e)

vui je sais, c'est pour cela que j'ai précisé que c'était pour la fonction (dec->Transparency) et non l'inverse, autrement on récupère la valeur DXF pour la convertir en valeur de transparence connue par l'utilisateur :3

Bisous,
Luna

Posté(e)
2 minutes ago, Luna said:

vui je sais, c'est pour cela que j'ai précisé que c'était pour la fonction (dec->Transparency) et non l'inverse, autrement on récupère la valeur DXF pour la convertir en valeur de transparence connue par l'utilisateur :3

Essaye :
(dec->Transparency 16777216)
et
(dec->Transparency 33554432)
tous les 2 renvoient 100 mais dans le premier cas, c'est DuBloc et dans le second 100% de transparence.

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

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

Salut (gile).

J'adore quand on me cite : "Il y a 10 types de personnes dans le monde : celles qui comptent en binaire et les autres" surtout quand ce n'est pas de moi, même si c'est dans ma signature...

Ô grand maître (gile)... 😉

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

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

Coucou,

J'ai une petite question concernant l'utilisation des flags de certaines fonctions. Certaines fonction AutoLISP utilise les bits comme arguments pour permettre la combinaison de plusieurs fonctionnalité en fonction d'une unique valeur numérique. Par exemple ci-dessous la fonction (initget) :

Signature

(initget [bits] [keywords])
bits

Type: Integer

A bit-coded that allows or disallows certain types of user input. The bits can be added together in any combination to form a value between 0 and 255. If no bits argument is supplied, zero (no conditions) is assumed. The bit values are as follows:

1 (bit 0) -- Prevents the user from responding to the request by entering only Enter.

2 (bit 1) -- Prevents the user from responding to the request by entering zero.

4 (bit 2) -- Prevents the user from responding to the request by entering a negative value.

8 (bit 3) -- Allows the user to enter a point outside the current drawing limits. This condition applies to the next user-input function even if the AutoCAD LIMCHECK system variable is currently set.

16 (bit 4) -- (Not currently used.)

32 (bit 5) -- Uses dashed lines when drawing a rubber-band line or box. For those functions with which the user can specify a point by selecting a location in the drawing area, this bit value causes the rubber-band line or box to be dashed instead of solid. (Some display drivers use a distinctive color instead of dashed lines.) If the AutoCAD POPUPS system variable is 0, AutoCAD ignores this bit.

64 (bit 6) -- Prohibits input of a Z coordinate to the getdist function; lets an application ensure that this function returns a 2D distance.

128 (bit 7) -- Allows arbitrary input as if it is a keyword, first honoring any other control bits and listed keywords. This bit takes precedence over bit 0; if bits 7 and 0 are set and the user presses Enter, a null string is returned.

256 (bit 😎 -- Give direct distance input precedence over arbitrary input. For external applications, arbitrary input is given precedence over direct distance input by default. Set this bit if you wish to force AutoCAD to evaluate user input as direct distance input. Note that legal point input from the keyboard always takes precedence over either direct distance or arbitrary input.

512 (bit 9) -- If set before a call to getpoint or getcorner, a temporary UCS will be established when the cursor crosses over the edge of a planar face of a solid. The temporary UCS is reset when the cursor moves off of a face. It is dynamically re-established when the cursor moves over a different face. After the point is acquired, the dynamic UCS is reset to the current UCS. This functionality is not enabled for non-planar faces such as the side of a cylinder.

1024 (bit 10) -- When calling getdist, getangle, getorient, getpoint, or getcorner, you may not want the distance, angle, orient, point, or corner to be influenced by ortho, polar, or otracking in the Z direction. Setting this bit before calls to any of these functions will temporarily disable ortho, polar, and otracking in the Z direction. This is useful when you create 2D entities such as a polyline, arc, or circle, or when you use the AutoCAD ARRAY command, which creates only a 2D array. In 2D-only commands it can be confusing and error-prone to allow 3D points to be entered using ortho Z, polar Z, or otrack Z.

Note: Future versions of AutoLISP may use additional initget control bits, so avoid setting bits that are not listed here.

Donc j'ai compris que l'utilisation de (logand) permet de déterminer si oui ou non un bit a été défini. Par exemple si l'on spécifie bit = 35 alors on aura :

(logand 35 1) returns 1.
(logand 35 2) returns 2.
(logand 35 4) returns 0.
(logand 35 8) returns 0.
(logand 35 16) returns 0.
(logand 35 32) returns 32.
(logand 35 64) returns 0.
(logand 35 128) returns 0.
(logand 35 256) returns 0.
(logand 35 512) returns 0.
(logand 35 1024) returns 0.

Mais du coup si on souhaite appliquer l'utilisation de bits comme argument, un (cond) ne peut pas faire l'affaire car il s'arrêterait à partir du bit 0 sans exécuter les bits 1 et 5 (comme (or) car fonctionnement similaire). La fonction (and) pourrait fonctionner, mais cela nécessite l'écriture en dur de chaque valeur donc pas optimal. Bref existe-t-il une fonction native relative à ce fonctionnement ou bien faut-il en développer une ?
J'avais commencer à développer une fonction pour repérer les bits présents dans un nombre entier positif avant de me rendre compte que (logand) permettait justement de les détecter...donc je préfères vérifier qu'AutoLISP ne fourni pas de fonction pour cette gestion d'arguments un peu particulier avant de me lancer dans la programmation de ma fonction ^^"

Bisous,
Luna

Posté(e)

Salut,

Je ne comprends pas bien la question (surtout avec initget qui est instancié par le programme est n'est actif que pour la première fonction get... suivant l'expression initget).

Sinon, il y a bin-list dans la bibliothèque MathGeom.lsp, en bas de cette page.

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

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é