2015-01-02 24 views
9

Sto utilizzando la classe Java Rectangle in un programma.Vincolare il rettangolo all'interno del rettangolo

Ho due Rectangle oggetti:

Rectangle big = new Rectangle(...); 
Rectangle small = new Rectangle(...); 

Le dimensioni specifiche dei rettangoli non sono importanti. Tuttavia, big sarà sempre più grande di small (in entrambi di larghezza e altezza).

Solitamente, small è interamente contenuto in big. Posso usare Rectangle#contains per verificarlo. Tuttavia, quando questo non è il caso, mi piacerebbe spostaresmall per essere interamente contenuto all'interno di big. Le dimensioni di nessuno dei due rettangoli dovrebbero cambiare.

Ad esempio:

Rectangles Example

So potrebbe usare quattro condizionali con Math.max e Math.min, ma c'è un modo più elegante di fare questo?

+0

ci sono quattro condizioni che si devono verificare, quindi non sono sicuro che si può andare via senza un "gruppo di condizionali" ... –

+0

Vero ... ma stavo cercando forse un'espressione di linea singola elegante, forse usando la classe 'Rectangle'. Forse non è possibile. – baum

+1

Un'espressione ternaria sarebbe "piccola" un po 'più pulita o più breve. – issathink

risposta

2

Si potrebbe fare solo con Math.max e Math.min. Prova qualcosa del genere:

small.setLocation(
    Math.max(Math.min(small.getX(),big.getX() - small.getWidth()),big.getX()), 
    Math.max(Math.min(small.getY(),big.getY() - small.getHeight()),big.getY()) 
); 

Tuttavia, dovresti considerare la leggibilità.

+0

hmm, questo è quello che temevo. Pensavo che forse avrei potuto usare un'inversione dell'intersezione ... forse no. – baum

+0

È più compatto, ma non quello che chiameremmo "elegante" –

+0

Sì, personalmente andrei con il quadruplo standard-ifs poiché è sempre usato per il controllo dei limiti, quindi un programmatore che deve mantenerlo dovrebbe riconoscerlo rapidamente . – Ghostkeeper

2

Hai bisogno di un design più forte. Se si estende sulla classe Rectangle, è possibile aggiungere la funzionalità esatta che si sta cercando. A quanto pare il "grande rettangolo" dovrebbe fungere da contenitore, contenente il rettangolo più piccolo:

class BigRectangle extends Rectangle { 
    //reference to or list of rectangle(s) here 

    private boolean isAlignedWith(Rectangle rect) { 
     return /* bounds logic */; 
    } 

    private void align(Rectangle rect) { 
     //move rectangle to proper position 
    } 

    public void add(Rectangle rect) { 
     if(!isAlignedWith(rect)) { 
      align(rect); 
     } 

     //store in reference or add to list 
    } 
} 

Ora, si può semplicemente aggiungere il rettangolo più piccolo a quello più grande:

Rectangle smallRectangle = new Rectangle(); 
BigRectangle bigRectangle = new BigRectangle(); 
bigRectangle.add(smallRectangle); //automatically aligns if needed 

Siete ora nascondendo la logica (necessaria), mantenendo pulita la tua unità centrale di codice. Questa è la mia opinione sul modo più elegante per gestire questo. (Vorrei anche probabilmente creare un'interfaccia RectangleContainer o ShapeContainer, avendo BigRectangle attuare tale. L'interfaccia dovrebbe contenere un metodo add(Rectangle) o add(SmallShape))