Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: Haddd en 02 de Abril de 2003, 09:18:38 AM

Título: Interpolación
Publicado por: Haddd en 02 de Abril de 2003, 09:18:38 AM
                                Tengo un problema de interpolación entre 4 puntos:

B   C

A   D

Cada pto representa la y, así por ejemplo:

20   30

10   40

Entre todos los puntos hay una distancia de 1. Entonces si me piden el punto (0,0.5) el valor debería ser 15. Si me piden el (1,1) el valor debería ser 30.

Lo que yo hago es trazar un vector del punto que me piden a cada uno de los 4 ptos y así obtengo el "peso" de cada punto sobre el que me piden. Esto es correcto, pero los que están en el centro se resolverían mas o menos así:

y=20*0.5+30*0.5+10*0.5+40*0.5=50

Pero yo no puedo tener ningún valor que supere el mayor de los puntos, es decir 40, por tanto algo hago mal.

¿Me ayudais?                                
Título: Interpolación
Publicado por: MA]Mestre en 02 de Abril de 2003, 09:31:33 AM
                                Siempre que hago interpolación entre dos puntos lo hago con interpolación lineal, interpolación por coseno o interpolación cúbica dependiendo del caso. Creo que la que buscas es la lineal.

Interpolación lineal

return a*(1-x) + b*x

siendo 'a' y 'b' los dos puntos a interpolar, y 'x' un valor entre 0 y 1. Cuando x es igual a 0 retorna a, cuando x es igual a 1 retorna el valor de b.

No se si es exactamente lo que buscas, pero espero que te sirva de ayuda.
a10.                                
Título: Interpolación
Publicado por: Haddd en 02 de Abril de 2003, 10:10:12 AM
                                Gracias pero no es así. Esta interpolación es entre 4 puntos y es un poco diferente. Compruébalo con el ejemplo que pongo                                
Título: Interpolación
Publicado por: Mars Attacks en 02 de Abril de 2003, 10:26:11 AM
                                Si es interpolación entre 4 puntos, ¿por qué en el primer ejemplo que has puesto sólo tomas en cuenta (en el caso del 0,0.5) el de arriba y el de abajo? Para calcular el valor en el centro podrías hacer la interpolación entre los dos de la izquierda (15, como ya has dicho), los dos de la derecha (35 si no recuerdo mal) y después la interpolación entre esos dos valores 15*0.5+35*0.5=25                                
Título: Interpolación
Publicado por: fiero en 02 de Abril de 2003, 11:19:19 AM
                                Pero, no se puede interpolar linealmente entre esos 4 puntos ¿no?. No puedes porque según las alturas que has puesto no se trata del mismo plano, sino de 2 triangulos cuyas normales no son iguales, así que no exixten las mismas pendientes en las dos mitades.

Yo dividiria el plano en 2 triangulos BCA y CDA  e interpolaria así:

u= entre 0.0 (izquierda) y 1.0 (derecha)
v= entre 0.0 (arriba) y 1.0 (abajo)

si el punto está en BCA:

y= B.y + u * (C.y - B.y) + v * (A.y - B.y);

si el punto está en CDA:

y= A.y + u * (D.y - A.y) + v * (C.y - A.y);


Si la distancia entre todos los vertices es 1 es facil saber que triangulo utilizar. Si x>z se utiliza CDA, y si no el otro, o algo así....
Esto está basado en el ejemplo pick de DX.

un saludo                                
Título: Interpolación
Publicado por: Haddd en 02 de Abril de 2003, 11:39:58 AM
                                Solo tomo en cuenta los dos de arriba porque en el cálculo omito aquellos que están a una distancia>1, porque asumo que no afectan para nada.                                
Título: Interpolación
Publicado por: jpastor en 02 de Abril de 2003, 03:19:24 PM
                                No se muy bien de que estais hablando, pero en el ejemplo que has puesto al principio, en el centro equivaldria a la media de los cuatro puntos, osea que es la formula que tu has puesto pero con 0.25

y=20*0.25+30*0.25+10*0.25+40*0.25=25

¿no se te habrá colado en 0.5 por error?                                
Título: Interpolación
Publicado por: jpastor en 02 de Abril de 2003, 03:37:19 PM
                                Ok, creo que he pillado quee asignas un peso a cada vertice que (1-distancia). Entonces el peso de cada vertice para un punto en el centro me sale (1-0.7071) = 0.2929 y el resultado en y = (20+30+10+40)*0.2929 = 29.2893 que está en el rango q esperas.

La duda, ¿haciendolo asi la interpolacion es lineal?                                
Título: Interpolación
Publicado por: Ithaqua en 02 de Abril de 2003, 04:26:18 PM
                                Haddd, la fórmula que has puesto no es correcta.
Si quieres hallar el centro geométrico el factor por el que tienes que multiplicar cada uno de los 'vértices' es 0.25. Ten en cuenta que sumando tus factores el resultado es 2 :)
Para hallar cualquier punto, suponiendo que quieras interpolación lineal, haz como cuando uno interpola valores gouraud.
Si tienes que calcular un (x, y) primero interpola verticalmente en las aristas izquierda y derecha para obtener los valores extremos del 'rasterline' donde se encuentra tu punto:
-------
|      |
x     x
|      |
-------
Luego vuelve a usar interpolación lineal para hallar el valor final dentro del rasterline horizontal:
-------
|      |
--x---
|      |
-------


Tu ejemplo para el (0.5, 0.5) sería:
-Extremo del rasterline izquierdo=10+(20-10)*y = 15
-Extremo del rasterline derecho =30+(40-30)*y = 35
Interpolamos entre 15 y 35: 15+(35-15)*x = 25                                
Título: Interpolación
Publicado por: Ithaqua en 02 de Abril de 2003, 04:27:16 PM
                                Ahora imagina por un momento que esos asciis están bien X-)                                
Título: Interpolación
Publicado por: Haddd en 02 de Abril de 2003, 04:31:22 PM
                                Es complejo, ¿eh?

Bueno, lo del triángulo me parece una buena idea, pero pienso que debe haber una solución más sencilla al problema. Se me ha ocurrido que tengo que normalizar al final el modulo de los 4 vectores que apuntan al pto que estoy buscando. Lo probaré y ya os diré cosas. Sin embargo, la cuestión sigue abierta                                
Título: Interpolación
Publicado por: ethernet en 02 de Abril de 2003, 08:29:39 PM
ithaqua, usa el bbcode list o code para q deje bien los asciis.

Por otra parte, como has implementado tu perlin noise haddd? En el codigo fuente del propio autor muestra como hace una interpolacion entre varios puntos (ademas lo hace hasta con 3 compoenentes) y usa la tecnica q ha descrito ithaqua, me parece la mas correcta y mas logica.

Ademas puedes implementarlo para un espacio con n componentes partiendo de como implementarlo en 1d(templates rocks). Precisamente en eso estaba yo trabajando ahora :))


saludos
Título: Interpolación
Publicado por: Ithaqua en 02 de Abril de 2003, 08:30:49 PM
                                Jarl, normalizar 4 vectores? :-?
No te compliques tantísimo la vida, prueba con lo que te he dicho, que son 3 sumas, restas y multiplicaciones :)
No se para que lo quieres exactamente, pero piensa que el problema es idéntico a cuando tienes un polígono con valores de color en sus vértices y tienes que rellenarlo interpolando. Primero se interpolan las aristas y luego se interpolan los rasterlines horizontales.                                
Título: Interpolación
Publicado por: ethernet en 02 de Abril de 2003, 08:38:47 PM
umh, algunos nacimos con opengl debajo del brazo y eso nos lo hace glcolor xDD
Título: Interpolación
Publicado por: Ithaqua en 02 de Abril de 2003, 08:44:07 PM
                                Voy a experimentar con el list, a ver...

Interpolar verticalmente las aristas laterales para obtener los valores extremos del 'rasterline' donde se encuentra el punto que buscamos:


-------

|     |

x     x

|     |

-------


Luego interpolar horizontalmente entre los extremos del 'rasterline' resultado para obtener el valor final:


--------

|      |

---x----

|      |

--------

                               
Título: Interpolación
Publicado por: Mars Attacks en 02 de Abril de 2003, 08:53:50 PM
                                Que es lo que le he dicho yo al principio, ¿no? :) Que interpole de dos en dos. Eso sí, tú te has explicado mejor. También iba a decirle lo del 0.25, pero no sé cómo he multiplicado yo (para asegurarme de que lo que decía estaba bien) que no me daba  :loco: torpe soy...                                
Título: Interpolación
Publicado por: Haddd en 02 de Abril de 2003, 10:37:51 PM
                                Bien, hallé la solución. Lo que me decís de interpolar primero en un lado y luego en otro, complica mucho el problema pq primero tienes que averiguar que dos vértices son los que tengo que coger, puesto que debo despreciar los otros dos. Además me parece muy duro no poder resolver este problema que parece tan sencillo.

Si cada punto recibe el impacto de cada vértice y el módulo del vector que forma el punto a estudiar con cada vértice me da el "peso" que afecta a cada vértice..¡debe funcionar! El problema era que yo no cumplía una última parte de la ecuación:

La suma de los pesos=1.

Y he aquí el código:

float Interpolar(float *yc,DWORD x,DWORD y,DWORD w,DWORD h)
{
   float vx,vy,d[4],Uno_Menos_vx,Uno_Menos_vy,vx2,vy2;

   vx=(float)x/(float)w;
   vy=(float)y/(float)h;
   
   vx2=vx*vx;
   vy2=vy*vy;

   Uno_Menos_vx=(1-vx)*(1-vx);
   Uno_Menos_vy=(1-vy)*(1-vy);

   // Calculamos la distancia del punto 0 al punto que nos dan
   // Si la influencia es <0 entonces que no influya
   
   d[0]=1-sqrtf(vx2+vy2);if(d[0]<=0) { d[0]=0;}
   d[1]=1-sqrtf(vx2+Uno_Menos_vy);if(d[1]<=0) { d[1]=0;}
   d[2]=1-sqrtf(Uno_Menos_vx+Uno_Menos_vy);if(d[2]<=0) { d[2]=0;}
   d[3]=1-sqrtf(Uno_Menos_vx+vy2);if(d[3]<=0) { d[3]=0;}

   float t=d[0]+d[1]+d[2]+d[3];

   d[0]/=t;d[1]/=t;d[2]/=t;d[3]/=t;

   return (yc[0]*d[0]+yc[1]*d[1]+yc[2]*d[2]+yc[3]*d[3]);
}

Dados 4 puntos y colocados según el índice

1   2

0   3

Y dada una posición x,y relativa a un w,h;la función nos calcula la y interpolada en ese punto.

Y lo utilizo en un generador de texturas de terreno pq necesito calcular la y de cada texel y no se corresponde en una relación 1 a 1 con el mapa del terreno.                                
Título: Interpolación
Publicado por: Ithaqua en 02 de Abril de 2003, 11:16:49 PM
                                Ouch, me parecen demasiados cálculos.
Si es en 3D y se trata de un terreno del que en principio no sabes como estan orientados los vértices, oriéntalos con algún método y luego usa vectores para interpolar según las aristas.                                
Título: Interpolación
Publicado por: mallrat en 03 de Abril de 2003, 01:42:13 AM
                                A  B
C  D

x: 0..1
y: 0..1

xi = 1.0 - x
yi = 1.0 - y

P = A*xi*yi + B*x*yi + C*y*xi + D*x*y                                
Título: Interpolación
Publicado por: Haddd en 03 de Abril de 2003, 09:18:38 AM
                                ¡Estoy utilizando vectores! Si lees el código verás que se calcula el módulo del vector desde cada vértice al pto que quiero estudiar para hallar su peso. Y es en 2D