Come rappresentare una linea geometrica a livello di codice?

5

Ho cercato di progettare una libreria per fare alcuni semplici calcoli geometrici in uno spazio euclideo, indipendentemente dalla sua dimensione. Sebbene sia facile rappresentare punti, vettori, ipersfere e iperpiani in modo generico, non riesco ancora a trovare un modo generico per rappresentare una linea (infinita), anche se le linee condividono le proprietà tra le dimensioni.

La mia ipotesi migliore è che potrei memorizzare alcuni dei parametri della sua equazione parametrica poiché è facile estendere un'equazione parametrica a una linea in uno spazio di qualsiasi dimensione:

x = x0 + at
y = y0 + bt
z = z0 + ct
// can be extended to any dimension

Ma anche con questa equazione, non riesco a trovare ciò che dovrebbe essere memorizzato e ciò che non dovrebbe essere al fine di confrontare le linee. Con una soluzione ideale, due oggetti di tipo Line :

  • sarebbe programmaticamente uguale (con operator== ),
  • avrebbe le stesse rappresentazioni in memoria.

Cosa devo conservare per raggiungere questo obiettivo?

    
posta Morwenn 18.12.2013 - 00:33
fonte

2 risposte

11

Penso che tu sia sulla strada giusta con la tua equazione parametrica.

Quello che hai è la forma vettoriale dell'equazione della linea.

L = R + tV

Dove R è [x0, y0, z0] e V è [a, b, c].

Hai solo bisogno di normalizzare le tue equazioni. Lo faresti trovando il valore di R tale che | R | è al minimo, che si verifica quando R è perpendicolare a V o R.V = 0.

Inoltre, poiché t può essere ridimensionato di qualsiasi valore, senza cambiare la linea, dovresti normalizzare V dividendo ogni coefficiente di | V |

    
risposta data 18.12.2013 - 02:54
fonte
5

Come minimo, tutto ciò che serve per confrontare le linee per l'uguaglianza è l'equazione parametrica che hai già.

Dati le linee L, M espresse come suggerisce Dancrumb:

L = X + tV
M = Y + tW

then L == M se V e W sono paralleli (o uguali se sono normalizzati alla lunghezza unitaria e qualche direzione "positiva"), e Y = X + tV per alcuni t.

Per ottenere l'uguaglianza dei membri, normalizzando la lunghezza del vettore & la direzione è il primo passo, ma è necessario anche qualche regola per normalizzare il punto. Ad esempio, potresti scegliere il punto sulla linea più vicino all'origine e utilizzarlo.

Pseudo codice per la normalizzazione di vettori e punti:

vec normalize_vec(vec v) {
  // 1. force unit length
  v = v/v.length();
  // 2. force positive direction
  for (int i = 0; i < v.dimension(); ++i) {
    if (v[i] < 0) {
      v = v * -1;
      break;
    }
    if (v[i] > 0)
      break;
    // keep going until the first nonzero element
  }
  return v;
}

point closest(point p, line l) {
  return (a-p).dot(l.vec) * l.vec;
}

line normalize_line(line l) {
  point new_pt = closest(point::origin, l);
  vec new_vec = normalize(l.vec);
  return line(new_pt, new_vec);
}
    
risposta data 18.12.2013 - 10:07
fonte

Leggi altre domande sui tag