Vediamo ora, attraverso degli esempi, cosa implicano concretamente questi attributi a seconda dei valori che possono assumere.
Ogni sottoelemento in Mobilia 'vive' in uno spazio tridimensionale delimitato dagli assi cartesiani XYZ, in cui l'intersezione degli assi (indicata da un circoletto rosso) rappresenta il punto (0, 0, 0):

Ogni sottoelemento è inoltre caratterizzato da un'origine, che corrisponde al vertice in basso a sinistra di un ideale parallelepipedo che avvolge l'elemento stesso (una sorta di ingombro del sottoelemento): nel caso dei nostri sottoelementi, il vertice in basso a sinistra di questi coincide con il vertice del parallelepipedo ideale; con altre geometrie questo non avviene: se guardiamo dall'alto un cilindro a base circolare ed un cilindro a base triangolare racchiusi nel parallelepipedo che ne determina l'ingombro, vediamo come l'origine (indicata da un circoletto blu) di tali geometrie cada addirittura al di fuori dei solidi in questione:

Un sottoelemento è caratterizzato anche da un centro implicito, che corrisponde al centro geometrico del parallelepipedo ideale che traccia l'ingombro delle varie geometrie utilizzate in Mobilia; riprendendo i nostri cilindri visti dall'alto, indichiamo il centro di queste geometrie con un circoletto verde:

Immaginiamo ora di voler realizzare un ennesimo tavolo, questa volta con un'unica gamba centrale (le dimensioni sono espresse in mm.):



Per 'costruire' questo tavolo, innanzitutto inseriamo i dati
relativi al suo ingombro.
Dalle misure in nostro possesso, appare evidente che il tavolino
avrà un ingombro pari a (X = 1500; Y = 770; Z = 1500).
L'origine dell'ingombro è sempre situata a (X = 0; Y =
0; Z = 0): il vertice in basso a sinistra del parallelepipedo
che rappresenta l'ingombro, in pratica, collima con il punto (X
= 0; Y = 0; Z = 0) dello spazio delimitato dagli assi cartesiani.

Pur non essendo vincolato a nessun sottoelemento, anche l'ingombro deve fare i conti con gli attributi che regolano i ridimensionamenti ed i riposizionamenti; gli attributi di riposizionamento sono ignorati, in quanto in Mobilia è sempre possibile riposizionare un elemento; nel caso invece degli attributi di ridimensionamento, assegneremo il valore fisso o parametrico a seconda che si voglia o meno permettere all'elemento di mutare le proprie dimensioni sui singoli assi.
Ad esempio, se vogliamo che il nostro tavolino possa crescere
in altezza ma non in larghezza né in profondità,
assegneremo il valore parametrico all'attributo
resizeMode_y, ed il valore fisso agli attributi resizeMode_x e
resizeMode_z.
Considerando che per il nostro esempio non intendiamo limitare
i ridimensionamenti in nessuna delle tre direzioni, i valori che
assegneremo all'ingombro saranno i seguenti:
&dimensioni: (1500; 770; 1500)
&posizioni: (0; 0; 0)
&resizeMode_x: parametrico
&resizeMode_y: parametrico
&resizeMode_z: parametrico
&repositionMode_x: parametrico
&repositionMode_y: parametrico
&repositionMode_z: parametrico
Una volta definito l'ingombro, passiamo al piano d'appoggio
del tavolino.
Questo sottoelemento è vincolato all'ingombro, e dunque
un riferimento al piano comparirà nella lista che l'ingombro
mantiene dei sottoelementi a sé legati.
Le dimensioni e le posizioni dei sottoelementi sono sempre relative
allo spazio determinato dagli assi cartesiani, e non alla posizione
e dimensione dell'elemento vincolante. Il nostro piano assume
dunque i seguenti valori:
dimensioni: (1500; 20; 1500)
posizioni: (0; 750; 0)
Il piano misurerà dunque 1500 mm sull'asse delle X e
delle Z, ed avrà uno spessore (asse delle Y) di 20 mm;
esso sarà inoltre situato a 750 mm di altezza (asse delle
Y).
Restano da assegnare i valori agli attributi di ridimensionamento
e riposizionamento. Le domande che ci dobbiamo porre sono le seguenti:
Come si ridimensiona il piano in relazione all'elemento vincolante?
Come si riposiziona il piano in relazione all'elemento vincolante?
Iniziamo dai ridimensionamenti: se l'ingombro che è l'elemento vincolante del piano cresce in larghezza (asse delle X), vogliamo che il piano cresca sull'asse delle X della stessa misura; pertanto, il valore corretto sarà:
resizeMode_x: costante
e con l'ingombro in rosso ed il piano in nero, visti dall'alto, avremo:

D'altro canto, se il valore attribuito a resizeMode_x fosse stato fisso, il piano non avrebbe seguito l'ingombro nel suo incremento:

Lo stesso discorso si estende all'asse delle Z, per cui il valore da attribuire sarà
resizeMode_z: costante
Ciò non vale, però, per l'asse delle Y: il piano,
qualora l'ingombro dovesse crescere in altezza, non dovrebbe crescere
a sua volta, ma dovrebbe semplicemente riposizionarsi.
Se noi erroneamente assegnassimo il valore costante all'attributo
resizeMode_y, avremmo, con il tavolino visto di fronte, i risultati
esemplificati in figura:

Quello che noi vogliamo, invece, è mantenere fisso lo spessore del piano, e modificarne la posizione sulle Y; tralasciando per un attimo la discussione sui riposizionamenti, possiamo senz'altro assegnare il valore fisso all'attributo resizeMode_y, per ottenere almeno la prima parte del risultato atteso

Dunque per il piano avremo i seguenti valori per gli attributi di ridimensionamento:
resizeMode_x: costante
resizeMode_y: fisso
resizeMode_z: costante
Resta ora da vedere come comportarci con gli attributi di
riposizionamento.
Continuiamo a discutere degli attributi del piano sull'asse delle
Y; nella figura precedente, il piano in questione non si è
ridimensionato e questo è corretto ma non si
è neanche spostato verso l'alto: questo sarebbe accaduto se il
valore
dell'attributo repositionMode_y fosse stato fisso. In realtà
il piano dovrebbe cambiare la propria posizione, spostandosi verso
l'alto della stessa misura di cui si è accresciuto l'ingombro.

Questo risultato è ottenibile assegnando il corretto valore all'attributo repositionMode_y:
repositionMode_y: costante
Sui rimanenti assi (XZ) il discorso è diverso.
Se l'ingombro si ridimensiona sull'asse delle X, noi vogliamo
che il piano cresca altrettanto sullo stesso asse, senza però
lasciare la propria posizione:

Questo implica i seguenti assegnamenti:
resizeMode_x: costante
repositionMode_x: fisso
Se per errore assegnassimo il valore costante all'attributo repositionMode_x, come conseguenza del ridimensionamento dell'ingombro, otterremmo anche uno spostamento dello stesso numero di millimetri sulle X:

Il che non corrisponde affatto a quello che intendiamo ottenere.
E poiché lo stesso ragionamento è applicabile all'asse
Z, i valori corretti per il sottoelemento piano saranno:
dimensioni: (1500; 20; 1500)
posizioni: (0; 750; 0)
resizeMode_x: costante
resizeMode_y: fisso
resizeMode_z: costante
repositionMode_x: fisso
repositionMode_y: costante
repositionMode_z: fisso
Passiamo dunque alla gamba centale, ultimo sottoelemento del nostro tavolino, che riproponiamo per comodità:

Dalle immagini ricaviamo immediatamente dimensioni e posizioni:
dimensioni: (500; 750; 500)
posizioni: (500; 0; 500)
vediamo quindi come si deve comportare questo sottoelemento
nei vari casi di ridimensionamento dell'ingombro, elemento vincolante
della gamba.
Il caso più semplice riguarda l'asse delle Y; noi infatti
vogliamo che la gamba cresca senza cambiare posizione, assecondando
lo spostamento verso l'alto del piano trattato in precedenza:

I valori corretti saranno dunque:
resizeMode_y: costante
repositionMode_y: fisso
sulla scorta dei quali la gamba non si sposterà da terra, ma accrescerà la propria altezza di tanti millimetri quanti quelli di cui è cresciuto l'ingombro.
Vediamo ora come gestire la gamba sui restanti assi.
Innanzitutto, questo sottoelemento non dovrebbe ridimensionarsi
sugli assi X e Z: vogliamo infatti che la gamba rimanga centrata
rispetto all'ingombro del tavolino (e dunque rispetto al piano),
mantenendo però le dimensioni originali. Il valore corretto
per gli attributi che ne controllano il ridimensionamento sarà
dunque fisso:
resizeMode_x: fisso
resizeMode_z: fisso
Ma quale valore dare agli attributi che impongono al sottoelemento il corretto riposizionamento? Finora abbiamo adottato solo due valori (fisso e costante), che tuttavia non garantiscono il risultato corretto:
con repositionMode_x: fisso la gamba resterà nella posizione precedente il ridimensionamento:

con repositionMode_x: costante la gamba si sposterà di un numero di millimetri pari a quelli di cui è cresciuto l'ingombro; pertanto, se da (X = 1500) passiamo a (X = 3000), la gamba - che prima del ridimensionamento è posizionata a 500 millimetri - sposterà la propria origine a (500 + 1500 = 2000) millimetri, mentre per mantenersi centrata avrebbe dovuto impostare la propria origine a 1250 millimetri:

Ed è a questo punto che entrano in gioco due ulteriori
valori per gli attributi di riposizionamento: proporzionale e
centratoProporzionale.
Come suggerisce il loro nome, questi due valori forzano un
sottoelemento
a mantenere una posizione proporzionale a quella precedente il
ridimensionamento dell'elemento vincolante. Ad esempio, se un
sottoelemento si trova in una posizione che è a 1/3 della
dimensione dell'elemento vincolante, dopo il ridimensionamento
di quest'ultimo si sposterà fino a riguadagnare una posizione
che è a 1/3 della nuova dimensione del vincolante. Quel
che differenzia i due valori è il punto del sottoelemento
rispetto al quale calcolare le proporzioni. Nel caso della nostra
gamba, non è l'origine a dover fare da riferimento, ma
il centro del sottoelemento; a noi interessa infatti che il centro
della gamba resti ad 1/2 della dimensione dell'ingombro:
repositionMode_x: centratoProporzionale

repositionMode_x: proporzionale

Il valore proporzionale può essere assegnato anche agli attributi di ridimensionamento; in questo caso il sottoelemento governato da un attributo di ridimensionamento proporzionale modificherà le proprie dimensioni al fine di mantenere la proporzione con l'elemento vincolante. Pertanto, se un sottoelemento è grande 1/3 dell'elemento al quale è vincolato, dopo il ridimensionamento di quest'ultimo tornerà ad essere 1/3 delle nuove dimensioni del vincolante. Nel caso della nostra gamba (le cui dimensioni sulle X sono appunto 1/3 delle dimensioni dell'ingombro) il raddoppio delle dimensioni dell'elemento vincolante comporterebbe il raddoppio delle proprie dimensioni. Con i seguenti assegnamenti
resizeMode_x: proporzionale
repositionMode_x: centratoProporzionale
faremo in modo che la gamba resti centrata sull'asse delle X e che le sue dimensioni sullo stesso asse siano comunque un terzo di quelle dell'ingombro:

Per meglio comprendere le interazioni fra gli attributi di
posizione e quelli di dimensione, analizziamo alcuni casi.
Negli esempi che seguono, la gamba ha le stesse dimenzioni, sull'asse
delle X, dell'ingombro:

Se l'ingombro cresce, intendiamo far sì che la gamba cresca con esso:

Poiché la gamba deve crescere della stessa misura di cui cresce l'ingombro, la soluzione più immediata è la seguente:
resizeMode_x: costante
repositionMode_x: fisso
cosicchè la gamba rimanga nella sua posizione crescendo però tanto quanto l'ingombro. Tuttavia lo stesso risultato lo possiamo ottenere con questi assegnamenti:
resizeMode_x: proporzionale
repositionMode_x: fisso
Infatti, poiché sull'asse X le dimensioni dell'ingombro
e quelle della gamba sono identiche, esiste una proporzione 1:1
tra le due; quando l'ingombro cresce, l'assegnamento resizeMode_x:
proporzionale fa sì che la gamba mantenga la proporzione
di uno ad uno con il vincolante, e fa crescere della stessa misura
la gamba stessa.
Ancora, possiamo anche adottare una soluzione nuova:
resizeMode_x: proporzionale
repositionMode_x: centratoProporzionale
O anche:
resizeMode_x: costante
repositionMode_x: centratoProporzionale
Questo perché assegnare il valore centratoProporzionale all'attributo repositionMode_x implica che il centro del sottoelemento debba mantenere la stessa posizione che aveva in proporzione prima del ridimensionamento: essendo il centro della gamba situato ad 1/2 della dimensione dell'ingombro, dopo il riposizionamento questo rapporto dovrà essere ristabilito.
Ora: qual è la soluzione più corretta? In realtà è solo una questione di preferenze personali; il risultato finale è identico in tutti i casi, e dunque l'unico criterio valido dovrebbe essere quello della leggibilità del codice: se una soluzione è più chiara di altre va senz'altro adottata. Ma il concetto di chiarezza è, a sua volta, qualcosa di decisamente soggettivo.
In casi più complessi, la struttura gerarchica rispecchia legami maggiormente articolati: se il nostro tavolo d'esempio avesse delle gambe composte da due segmenti invece di essere realizzate in un unico blocco (vedi fig.)
allora dovremmo esprimere i seguenti vincoli:
1) L'ingombro non ha vincoli
2) Il piano è vincolato all'ingombro
3) I segmenti superiori delle gambe sono vincolati all'ingombro
4) I segmenti inferiori delle gambe sono vincolati ai rispettivi
segmenti superiori
In base alla supposta disposizione gerarchica, una modifica all'ingombro comporterebbe un eventuale contraccolpo sui quattro segmenti superiori, essendo questi all'ingombro vincolati; se e solo se alcuni dei segmenti superiori delle gambe dovessero a questo punto aver subito delle modifiche alle dimensioni, i corrispondenti segmenti inferiori dovrebbero rivalutare i valori dei propri attributi in base ai vincoli che li legano ai segmenti superiori.
Ciascun sottoelemento ha degli attributi che specificano come reagire alle eventuali modifiche delle dimensioni dell'elemento a cui sono vincolati; per il nostro esempio sono sufficienti le norme che regolano il ridimensionamento sull'asse delle X (crescita in larghezza):
Piano
Se l'elemento a cui sono vincolato cresce in larghezza,
incrementerò
la mia dimensione sull'asse delle X della differenza tra
la larghezza originaria e quella corrente.
Gamba Superiore
Se l'elemento a cui sono vincolato cresce in larghezza,
incrementerò
la mia posizione sull'asse delle X della differenza tra
la larghezza originaria e quella corrente.
Gamba inferiore
Se l'elemento a cui sono vincolato cresce in larghezza,
incrementerò
la mia posizione sull'asse delle X della metà della
differenza tra la larghezza originaria e quella corrente (ovvero,
riguadagno una posizione centrata).
Apportiamo ora una modifica alla larghezza dell'ingombro, incrementandola di 15 centimetri, e vediamo come ciascun sottoelemento reagisce sulla scorta dei vincoli che possiede:
la nuova dimensione dell'ingombro comporta ripercussioni sugli elementi direttamente vincolati a questo (piano e gamba superiore): il piano modificherà la propria dimensione (ma non la posizione) dei 15 centimetri di cui è cresciuto l'ingombro e la gamba superiore modificherà la propria posizione (ma non la dimensione) degli stessi 15 centimetri.
Cosa è accaduto alla gamba inferiore? Questa non è direttamente vincolata all'ingombro, ma è direttamente vincolata alla gamba superiore; se come conseguenza del ridimensionamento dell'ingombro la gamba superiore avesse dovuto modificare le proprie dimensioni, allora la gamba inferiore avrebbe conseguentemente riveduto la propria posizione relativa alla gamba superiore, centrandosi rispetto ad essa: se dunque la dimensione della gamba superiore fosse cresciuta di 15 centimetri, la gamba inferiore si sarebbe spostata di (15 / 2) = 7.5 centimetri sull'asse delle X.
Ma poiché è cambiata solo la posizione della gamba superiore, nulla è mutato dal punto di vista della gamba inferiore, e, nello spostarsi rispetto all'ingombro, la gamba superiore trascinerà con se la propria metà inferiore, che resterà nella sua posizione originaria relativa alla gamba superiore.
Resta ora da vedere come imporre una strutturazione gerarchica ai vari sottoelementi e come controllare il modo in cui le dimensioni e le posizioni di ciascun sottoelemento reagiscono alle modifiche apportate alle dimensioni dell'ingombro.
Struttura e attributi di controllo
La strutturazione è ottenuta in
maniera
molto semplice: ciascun sottoelemento ingombro compreso
mantiene una lista dei sottoelementi ad esso vincolati.
Nell'esempio del primo e più semplice tavolo, l'ingombro
avrà una lista contenente un riferimento a ciascuna delle
quattro gambe ed al piano, mentre questi avranno una lista vuota;
nel caso del tavolo con le gambe in due pezzi, l'ingombro avrà
una lista con riferimenti al piano ed ai quattro segmenti superiori
delle gambe, il piano avrà una lista vuota, ciascun segmento
superiore di gamba avrà un riferimento al proprio segmento
inferiore, e ciascun segmento inferiore avrà una lista
vuota.
Per determinare il modo in cui un sottoelemento reagisce alle
modifiche apportate al sottoelemento a cui è vincolato
si fa invece uso di un insieme di attributi assoluti (ed in quanto
tali svincolati ed immutabili) i cui valori non sono altro che
delle precise indicazioni sul modo in cui ciascun sottoelemento
deve comportarsi.
Torniamo al tavolo d'esempio con le gambe in due segmenti.
Ciascun sottoelemento inoltre è
caratterizzato
da un insieme di attributi che condizionano il modo in cui questo
reagisce ai ridimensionamenti apportati all'elemento vincolante:
ATTRIBUTI
resizeMode_x Controlla la modalità di ridimensionamento
sull'asse dell X
resizeMode_y Controlla la modalità di ridimensionamento
sull'asse dell Y
resizeMode_z Controlla la modalità di ridimensionamento
sull'asse dell Z
repositionMode_x Controlla la modalità di riposizionamento
sull'asse dell X
repositionMode_y Controlla la modalità di riposizionamento
sull'asse dell Y
repositionMode_z Controlla la modalità di riposizionamento
sull'asse dell Z
Questi attributi possono assumere uno dei seguenti valori:
VALORI DIMENSIONI (resizeMode)
fisso La dimensione del sottoelemento rimane immutata
costante La dimensione del sottoelemento viene incrementata dello
stesso valore di cui è incrementato l'elemento vincolante
proporzionale Il sottoelemento si ridimensiona fino a raggiungere
la stessa proporzione che aveva rispetto all'elemento vincolante
prima del ridimensionamento di questo
centratoProporzionale Stessa funzione di 'proporzionale'
parametrico Usato per l'ingombro
VALORI POSIZIONI (repositionMode)
fisso La posizione del sottoelemento rimane immutata
costante La posizione del sottoelemento viene incrementata dello
stesso valore di cui è incrementata la dimensione del l'elemento
vincolante
proporzionale La posizione dell'origine del sottoelemento viene
incrementata fino a trovarsi nella stessa posizione relativa che
aveva rispetto all'elemento vincolante prima del ridimensionamento
di questo
centratoProporzionale La posizione del centro del sottoelemento
viene incrementata fino a trovarsi nella stessa posizione relativa
che aveva rispetto all'elemento vincolante prima del ridimensionamento
di questo parametrico Usato per l'ingombro