Ma ora ti va? Perche'
codice:
for(int i=0; i<n; i++){
	for(int x=i+1; x<n; x++){
		double sott = Math.abs(punti[i]-punti[x]);
		sottr[puntatore] = sott;
		puntatore++;
        }
}
All'ultimo giro, i=2. Entro nel for interno, x=i+1=2+1=3. Controllo la guardia, 3<3 è falso. Esco dal for interno. Torno all'inizio del for esterno i=i+1=3. Controllo la guardia, 3<3 è falso. Esco dal for esterno e vado avanti con il programma.
Ora, va benissimo mettere n-1 nel ciclo for esterno, in qesto modo risparmi 2 controlli, ma dal punto di vista del risultato finale non cambia niente, perche' la passata di for interno in cui accedi a punti[3] non verra' mai fatta.
Ad esempio la classe sotto fa la stessa cosa(ho fatto copia e incolla del for) ma non solleva nessuna eccezione.
codice:
public class ArrayTest {
    public static void main(String args[]) {
        int[] punti = {3,2,1};
        int n = punti.length;
        double[] sottr = new double[3]; //3 = 3!/(2*(3-2))
        int puntatore = 0;
        for(int i=0; i<n; i++){
            for(int x=i+1; x<n; x++){
                double sott = Math.abs(punti[i]-punti[x]);
                sottr[puntatore] = sott;
                puntatore++;
            }
        }
        for(int i=0; i<puntatore; i++) {
            System.out.println(sottr[i]);
        }
    }   
}
Inoltre l'eccezione che hai postato dice:
java.lang.ArrayIndexOutOfBoundsException: 9
cioe' in qualche parte del codice (riga 47) stai cercando di accedere alla posizione 9 dell'array. Ora siccome, se n=3, non arrivi mai alla posizione 9, mi viene il dubbio che l'errore non sia in questo punto.