2013-03-08 9 views
7

probabilmente non è il posto giusto per postare questo, ma non so dove altro postarlo.Formula generale per calcolare le distanze uguali dello spazio 3d

ho 5 linee (d1 -> d5) equamente distribuite l'una dall'altra in prospettiva 3d, ho i valori di (a) angolo, (d1) e (b5). ho bisogno di calcolare (b2, b3, b4, d2, d3, d4, d5) con jquery.

enter image description here

posso calcolare D5 con:

d5 = d1 - (b5 * Math.tan(a)) 

ma non ho idea di come calcolare B2, B3 e B4. (d1 è diviso in 4 segaments (s) identici) qualsiasi aiuto sarebbe apprezzato.

+0

Potrebbe essere http://math.stackexchange.com che si desidera. +1 per l'immagine comunque. – Popnoodles

+0

Primo: questa domanda è fantastica. Secondo: @popnoodles è probabilmente corretto. Terzo: stai cercando i valori di lunghezza per ogni segmento di linea? –

+0

@popnoodles: grazie pubblico qui ora – razzak

risposta

2

Quello che stai cercando è una scala proiettiva. Il modo più semplice per farlo computazionalmente è usare le coordinate omogenee, prendere un rettangolo (come quello nella prima immagine sotto) su cui V è "infinitamente lontano a destra" e trovare una trasformazione proiettiva che mappa questo rettangolo al trapezio in la seconda immagine. I vertici del rettangolo sono (0 | 0), (0 | d1), (b5 | d1), (b5 | 0) e i corrispondenti vertici del trapezio sono (0 | 0), (0 | d1), (b5 | d5), (b5 | 0).

Illustration of a projective transformation for obtaining a projective scale

Poiché questi sono quattro punti di cui non allineati, possiamo trovare una matrice unica (fino a scalare) M per questa trasformazione. Dopo alcuni matematica, si scopre che questa matrice è:

[d1*b5,0,0] 
[0,b5*d5,0] 
[d1-d5,0,b5*d5] 

Se si desidera trovare le coordinate B3 e D3, per esempio, è possibile moltiplicare questa matrice con le coordinate omogenee del punto al centro della linea , cioè il vettore (0,5 * b5, d1,1)^T e ottieni le coordinate omogenee del punto (b3 | d3), che può essere convertito in coordinate euclidee mediante la deomogenazione, ovvero dividendo le prime due componenti per il terzo.

In generale, se si hanno due punti (b1 | d1) e (bn | dn) e si vogliono conoscere le coordinate di n-2 punti equidistanti tra loro su una scala proiettiva come questa, è possibile calcolare le coordinate bi e di come in questo modo (nel tuo caso, n sarebbe 5, ovviamente):

let M := matrix [[d1*bn, 0, 0], [0, bn*dn, 0], [d1-dn, 0, bn*dn]] 
let v := ((i-1)/(n-1)*bn, d1, 1) 
let (x,y,z) := M*v 
let bi := x/z and di := y/z 

come si vede, si tratta di un semplice algoritmo per calcolare le coordinate di questi punti proiettivamente equidistanti, e generalizza ben arbitrariamente numeri di punti.

Se si preferisce avere una formula chiusa, si può calcolare la bi e di direttamente come:

let bi := (bn*d1*(i-1))/(dn*n+(d1-dn)*i-d1) 
let di := d1*dn*(n-1)/(dn*n+(d1-dn)*i-d1) 
+0

grazie per la tua risposta, ma come posso usarlo in jquery ?! – razzak

+0

Senza offesa, ma JavaScript è un linguaggio direttamente dall'inferno e non lo toccherò. Tuttavia, non vedo il problema - tutto ciò che devi fare è scrivere il codice JavaScript per le ultime due righe di codice che ho postato, che non dovrebbe essere troppo difficile in alcun linguaggio di programmazione. Forse qualcosa come http://pastebin.com/T3yuyTW3. b [1], b [5], d [1], d [5] devono contenere i valori appropriati all'inizio del programma, le altre voci b e d verranno quindi inserite nel ciclo. (Non ho idea se questo sia JavaScript valido, ma dovrebbe esserne il succo) –

+0

assumendo che le due formule siano corrette 'let bi: = (bn * d1 * (i-1))/(dn * n + (d1-dn) * i-d1) let di: = d1 * dn * (n-1)/(dn * n + (d1-dn) * i-d1) ' se cambio l'angolo (a) non sembra avere alcun effetto sulla formula! – razzak

0

enter image description here

Prima dobbiamo calcolare che la lunghezza del lato adiacente dell'intero triangolo d1 ->v ->c è (lato sinistro verticale di esso):

tan(Θ) = opposite/adjacent 
opposite * tan(Θ) = adjacent 
adjacent = opposite * tan(Θ) 
adjacent = d1 * tan(a) 

la prossima cosa abbiamo bisogno è sapere quanto da terra ogni riga da v è quando si arriva alla linea d1. Dato che variabile s è la stessa per tutte le divisioni e supponendo N dividendo segmenti (in questo caso 3), il nostro contatore è i che comincia da 1 e va a N:

opposite(i) = i * (d1/N) 

ora abbiamo bisogno l'angolo che la linea da v ad ogni marcatore s fa:

tan(Θi) = opposite/adjacent 
Θi = arctan(opposite/adjacent) 
Θi = arctan(opposite(i)/adjacent) 
Θi = arctan((i * (d1/N))/(d1 * tan(a))) 

Usando qualche geometria/trig possiamo dire che l'angolo va da d1 attraverso il punto c all'inizio di d5 è (90 ° - a).Chiameremo questo angolo un '

a' = 90° - a 

il diritto di seni ci dice che:

A'/sin(a') = opposite(i)/sin(b') 

così ora risolviamo per A' da quando abbiamo bisogno di aiuto con ottenere le dimensioni del quadrato arancione :

A' = (opposite(i) * sin (a'))/sin(b') 

dal b' = (un + Θi) questo si trasforma in:

A' = (opposite(i) * sin (90° - a))/sin(a + Θi) 

Stessa cosa applicata ma solving per h nel triangolo arancione (vedi foto):

h/sin(90°-Θi) = A'/sin(90°) 
h = (A' * sin(90°-Θi))/sin(90°)  
b2 = h 

Mettendo tutto insieme (si spera senza copia/incolla errori da parte mia) e senza semplificazioni:

b2 = ((((i * (d1/N)) * sin (90° - a))/sin(a + Θi)) * sin(90° - arctan((i * (d1/N))/(d1 * tan(a)))))/sin(90°)  

Ora risciacquo/ripetizione per ogni valore di i e trasformo in codice (l'avrei fatto ma sono troppo stanco) :)

+0

'tan (Θ) = opposto/adiacente - -> adiacente = opposto/tan (0) 'giusto? – razzak

+0

sì :) Come per un ', è perché il triangolo dei punti b5-> d5-> c ha un totale di 180 gradi all'interno. uno di questi è 90 e l'altro è a, quindi l'angolo rimanente è 180-90-a = 90-a anche se potresti avere ragione a riguardo dipendendo da b5 –

Problemi correlati