Fórmula general para calcular el espacio en 3D a distancias iguales

probablemente no sea el lugar correcto para publicar esto, pero no sé dónde más publicarlo.

Tengo 5 líneas (d1 -> d5) distribuidas equitativamente una de otra en perspectiva 3D, tengo los valores de (a) ángulo, (d1) y (b5). Necesito calcular (b2, b3, b4, d2, d3, d4, d5) con jquery.

enter image description here

Puedo calcular d5 con:

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

pero no tengo idea de cómo calcular b2, b3 y b4. (d1 se divide en 4 segaments (s) idénticos) cualquier ayuda sería apreciada.

Lo que estás buscando es una escala proyectiva. La forma más fácil de hacer esto computacionalmente es usar coorderadas homogéneas, tomar un rectángulo (como el de la primera image a continuación) en el que V está "infinitamente lejos a la derecha" y encontrar una transformación proyectiva que mapea este rectángulo con el trapecio en la segunda foto Los vértices del rectángulo son (0 | 0), (0 | d1), (b5 | d1), (b5 | 0) y los vértices correspondientes del trapecio son (0 | 0), (0 | d1), ( b5 | d5), (b5 | 0).

Ilustración de una transformación proyectiva para obtener una escala proyectiva

Dado que estos son cuatro puntos, de los cuales tres no son colineales, podemos encontrar una matriz única (hasta la escala) M para esta transformación. Después de algunas matemáticas, resulta que esta matriz es:

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

Si quiere encontrar las coorderadas b3 y d3, por ejemplo, puede multiplicar esta matriz con coorderadas homogéneas del punto en el medio de la línea, es decir, el vector (0.5 * b5, d1,1) ^ T y obtiene el coorderadas homogéneas del punto (b3 | d3), que pueden convertirse en coorderadas euclidianas por deshomogeneización, es decir, dividir las dos primeras componentes por la tercera.

En general, si tiene dos puntos (b1 | d1) y (bn | dn) y desea conocer las coorderadas de n-2 puntos equidistantes entremedio en una escala proyectiva como esta, puede calcular las coorderadas bi y di como esta (en su caso, n sería 5, por supuesto):

 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 

Como puede ver, este es un algorithm simple para calcular las coorderadas de estos puntos equidistantes proyectivos, y se generaliza a numbers arbitrarios de puntos.

Si prefiere tener una fórmula cerrada, puede calcular el bi y di directamente como:

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

enter image description here

Primero, debemos calcular cuál es la longitud del lado adyacente del triángulo integer d1 -> v -> c (el lado vertical izquierdo):

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

Lo siguiente que necesitamos es saber qué tan lejos del suelo está cada línea de v cuando llega a la línea d1 . Dado que la variable s es la misma para todas las divisiones y asumiendo N segmentos divisorios (en este caso 3), nuestro contador es i que comienza desde 1 y va a N :

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

Ahora necesitamos el ángulo de esa línea desde v hasta las marcas de cada marcador:

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

Usando un poco de geometry / trig, podemos decir que el ángulo que va de d1 a través del punto c a la parte superior de d5 es (90 ° – a). Llamaremos a este ángulo '

 a' = 90° - a 

La ley de los senos nos dice que:

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

así que ahora resolvemos para A 'ya que necesitamos ayuda para get las dimensiones del cuadrado naranja:

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

dado que b ' = ( a + Θi ) esto se convierte en:

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

Lo mismo aplicado pero resolviendo h en el triángulo naranja (ver image):

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

Poniendo todo junto (ojalá sin errores de copyr / pegar de mi parte) y sin simplificaciones:

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

Ahora enjuague / repita para cada valor de i y conviértalo en código (lo habría hecho pero estoy demasiado cansado) 🙂