[résolu] keypad vs getOffset

Répondre
Partager Rechercher
Bonjour,

Vous connaissez certainement cette petit fonction magique proposée par Very Keynes en 2008.
Code PHP:

integer cols 8;
integer rows 16;
integer keypad(vector loc) {return 10 llFloor(loc.cols) + (rows llFloor(loc.rows) - 1);} 
J'ai pris un cube et une texture avec une grille de 64 cases (8x8).
Ensuite j'ai fais une "petite" fonction pour l'offset de la texture.
Code PHP:

vector getOffset(integer case)
{
    
vector offset;

    
// Ligne 1
    
if (case == 0)  offset = <-0.43750.43750.0>;
    if (case == 
10offset = <-0.31250.43750.0>;
    if (case == 
20offset = <-0.18750.43750.0>;
    if (case == 
30offset = <-0.06250.43750.0>;
    if (case == 
40offset = <0.06250.43750.0>;
    if (case == 
50offset = <0.18750.43750.0>;
    if (case == 
60offset = <0.31250.43750.0>;
    if (case == 
70offset = <0.43750.43750.0>;

    
// Ligne 2, 3, 4 ...
    
return offset
Sur les faces verticales (faces 1, 2, 3, 4) j'affiche le damier (8x8) et sur la face supérieur (face 0) une texture blanche.
Quand on clic sur l'une des cases du damier (faces verticales), le motif de la case touchée s'affiche en grand sur la face supérieur à la place de la texture blanche.

Tout fonctionne mais 70 lignes de code pour la fonction getOffset je trouves ça lourd et peu éléguant.

Ma demande est la suivante, ne serait-il pas possible d'avoir une belle petite fonction magique comme keypad mais cette fois pour getOffset ?

Evidement que oui mais comment ?

Merci d'avance.

Dernière modification par djphil ; 02/10/2015 à 21h45. Motif: résolu
Code PHP:

vector getOffset(integer case)
{
integer icolonne = case/10;
integer iligne = case%10;
return <-
7+2*icolonne7-2*iligne0.0>/16.0;

En effet, 70 lignes ne sont pas vraiment indispensables
Il y a comme ça quelques opérateurs que je n'utilise jamais car je ne les comprends pas.
"%" en fait partie au même titre que ">>", "<<" et "^".

Nickel Matou, merci
Cliquez ce bouton ou survolez le contenu pour afficher le spoiler
Une ligne en moins, je suis preneur

Dernière modification par djphil ; 07/04/2015 à 12h18.
Un autre cas d'offset désesperé ici
Je ne suis jamais parvenu à créer la texture du boutton optionnel "highlight"

edit: sauf aujourd'hui
getTexture

Dernière modification par djphil ; 19/04/2015 à 23h45.
Citation :
Publié par djphil
Il y a comme ça quelques opérateurs que je n'utilise jamais car je ne les comprends pas.
"%" en fait partie au même titre que ">>", "<<" et "^".
Ces opérateurs sont souvent indispensables.

Prenons le cas de %. Il permet de trouver le reste d'une division. Par exemple si on fait 10%3 on va obtenir 1 parce que si on divise 10 par 3 on obtient 3 et il reste 1. Une application courante est pour trouver la parité, si on a un nombre x et qu'on veut déterminer s'il est pair ou impair. On fait x%2 et on teste le résultat, si le nombre est pair le résultat est 0 sinon c'est 1. On utilise cette propriété par exemple pour changer la couleur de fond des tableaux d'une ligne sur deux sur les pages web.

Pour >> et << c'est un peu plus délicat parce que ce sont des opérateurs qui jouent sur les bits. Les deux opérateurs servent à les décaler à droite ou à gauche. Prenons un exemple :

Un octet : a=00000100 ce qui en décimal est égal à a=2^2=4

Si je décale d'un cran vers la gauche : a<<1 ça donne l'octet a=00001000=2^3=8 (on a donc multiplié par 2)

Si je décale d'un cran vers la droite : a>>1 ça donne l'octet a=00000010=2^1=2 (on a donc divisé par 2)

Dernière modification par bestmomo ; 07/04/2015 à 13h09.
Citation :
Publié par djphil
Quand je divise 10 par 3, j'obtiens 3.33333333 moi ...
Je parlais de l'entier qu'on obtient et ce n'est effectivement pas 9 mais 3 et j'ai corrigé (je tape trop vite !), je n'ai pas été assez précis. On obtient 3 si on s'arrête avant la virgule et il reste 1 .
Citation :
Publié par black cats
Code PHP:

-7+2
7
-2
/16.0 
Pourquoi -7+2 et 7-2 ?
7 correspond t'il à cols - 1 ?
Et 2, pourquoi 2 ?
16.0 c'est le Float de rows ?

D'où sortent tous ces chiffres ?
Citation :
Publié par djphil
D'où sortent tous ces chiffres ?
De ma poche
Ou plutôt, des chiffres que tu donnes dans ton propre script.

Les cases 0,10,20,30,40,50,60,70 sont les cases de la première ligne.
On peut numéroter 0 à 7 les 8 colonnes. Le numéro de la colonne s'obtient en divisant le numéro de case par 10.

D'une colonne à l'autre, tu décales l'offset en X de 0.125, c'est à dire 1/8, ce qui est logique.
En regardant toujours tes valeurs, on voit que par exemple, pour la colonne 4, l'offset vaut 0.0625, c'est à dire 1/16. A partir de là, si on remonte de 4 colonnes, on a

pour la colonne 0 : offsetX = 1/16-4/8 = -7/16 = -0.4375

Et, puisqu'on rajoute 1/8 = 2/16 à chaque nouvelle colonne, on a
pour une colonne quelconque : offsetX = (-7+2*numero_de_colonne)/16

Ensuite, il y a l'offset en Y.
En regardant toujours tes valeurs, on voit que pour ta première ligne (il est plus commode de l'appeler ligne numéro 0), l'offset en Y ne change pas, et vaut +0.4375 = +7/16
J'imagine que dans ce cas là, tu diminues l'offset de 1/8 à chaque changement de ligne, dans l'autre sens cette fois-ci, c'est à dire en ajoutant -1/8 à chaque changement de ligne.
D'où offsetY = (+7-2*numero_de_ligne)/16


Pour revenir sur les problèmes de division, euclidienne ou décimale, reste etc, et ajouter quelques compléments a ce qu'explique le chat de gouttière plus haut :

Il y a deux façons de diviser.
Si tu as un paquet de farine de 1.4 kg, à partager entre 4 personnes, tu pourras toujours faire 4 paquets de masse identique. Appelons ça une division décimale.
Si tu as 14 pommes à partage entre 4 personnes, et pas de couteau pour les découper, tu donneras 3 pommes à chacun, et il te restera 2 pommes.
Ca s'appelle une division euclidienne. On ne considère que des nombres entiers, et comme en général ça ne tombe pas pile, il y a un reste.


On a besoin d'extraire le numéro de la colonne et le numéro de la ligne, pour un numéro de case donné.
Les cases 20,21,22,23... , sont toutes sur la ligne numéro 2 (si on commence à numéroter par 0 la première ligne).
La division euclidienne par 10 permet facilement d'obtenir alors le numéro de la ligne.
Et le reste de la division par 10 donne le numéro de la colonne.
On pourrait l'obtenir par :
Code PHP:

integer icolonne = case/10;
integer iligne = case - (10*icolonne); 
Mais puisque qu'on met à notre disposition une fonction qui nous donne le reste directement :
Code PHP:

integer iligne = case%10
Ce qui complique un peu les choses, c'est que le langage permet de faire au choix des divisions euclidiennes, ou des divisions décimales, mais que le signe utilisé est "/" dans les deux cas.
Citation :
Publié par djphil
Quand je divise 10 par 3, j'obtiens 3.33333333 moi ...
Code PHP:

integer a 10/3
On divise un entier par un autre entier. Le résultat est un entier, par la division euclidienne :
a = 3
Code PHP:

float a 10/3
On divise toujours un entier par un entier. Le compilateur interprète le signe "/" comme une division euclidienne. La variable a étant déclarée comme un nombre décimal, on obtient un entier, converti en décimal :
a = 3.0000
Code PHP:

float a 10/3.0
Code PHP:

float a 10.0/3
Le dividende ou le diviseur (ou les deux) étant un nombre décimal, le compilateur interprète le "/" comme une division décimale. Le résultat est :
a = 3.33333

Allez, pour finir, et puisqu'on parlait du loup
Citation :
Publié par bestmomo
Allez le matou je suis sûr que tu peux gagner une ligne .
Ouuuuuh le vilain taquin.langue2.gif
L'idée était de privilégier la lisibilité, qui me semblait plus importante ici, que la concision
Alors bon, à la demande générale, je joins une version à une ligne au lieu de 6.
Code PHP:

vector getOffset(integer c) {return <c/10*2-7,7-c%10*2,.0>/16.;} 

Je pense qu'on approche la limite inférieure du nombre de caractères
Ok ok, on peut gagner encore un peu, en supprimant les deux points décimaux, en raccourcissant le nom de la fonction...
Mais bon, là, j'enverrai une facture
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés