|
POV-Ray requiere muy amenudo que especifiques vectores. Un vector en
un conjunto de valores de coma flotante relacionados. Los vectores
pueden especificarse usando literales, identificadores o funciones que
devuelvan valores de tipo vector. También puedes crear expresiones muy
complejas usando combinaciones de los anteriores, usando los operadores
tradicionales.
Los vectores de POV-Ray pueden tener de 2 a 5 componentes, pero la mayoría tienen 3 componentes. Salvo que se especifique lo contrario,
debes asumir que la palabra "vector" se refiere a un vector de tres
componentes. POV-Ray opera en un sistema de coordenadas de tres
dimensiones (x
, y
y z
), y tienes
que usar vectores de tres componentes para especificar los valores x
,y
y z
. En algunas ocasiones, POV_Ray necesita sólo dos
coordenadas, que se especifican normalmente usando un vector 2D llamado
"vector UV". Los objetos fractales usan vectores de 4 dimensiones. Las
expresiones de color utilizan vectores 5D, aunque te permiten
especificar 3, 4 ó 5 componentes y usar los valores por defecto para los
no especificados. Salvo que se indique lo contrario, los vectores de 2,
4 ó 5 componentes funcionan igual que los vectores 3D, excepto que
tienen un número diferente de componentes.
La sintaxis para combinar literales de vector en las expresiones vectoriales es prácticamente idéntica a la de las expresiones de coma flotante. En la sintaxis de expresiones vectoriales a continuación, algunos de los items de sintaxis se definen en la sección referente a expresiones de coma flotante. Vea "Expresiones de coma flotante" para conocer esas definiciones. En las siguientes subsecciones se detallan las características específicas de vectores.
VECTOR: NUMERIC_TERM [SIGN NUMERIC_TERM] NUMERIC_TERM: NUMERIC_FACTOR [MULT NUMERIC_FACTOR] NUMERIC_FACTOR: VECTOR_LITERAL | VECTOR_IDENTIFIER | SIGN NUMERIC_FACTOR | VECTOR_FUNCTION | VECTOR_BUILT-IN_IDENT | ( FULL_EXPRESSION ) | ! NUMERIC_FACTOR | FLOAT VECTOR_LITERAL: < FLOAT , FLOAT , FLOAT > VECTOR_FUNCTION: min_extent ( OBJECT_IDENTIFIER ) | max_extent ( OBJECT_IDENTIFIER ) | trace(OBJECT_IDENTIFIER, VECTOR, VECTOR, [VECTOR_IDENTIFIER] )| vaxis_rotate( VECTOR , VECTOR , FLOAT ) | vcross( VECTOR , VECTOR ) | vrotate( VECTOR , VECTOR ) | vnormalize( VECTOR ) | vturbulence(FLOAT, FLOAT, FLOAT, VECTOR) VECTOR_BUILT-IN_IDENT: x | y | z | t | u | v
Nota: VECTOR_IDENTIFIERS identificadores previamente declarados que contienen valores vectoriales.
Los literales vectoriales consisten en un conjunto de entre 2 y 5
expresiones de coma flotante, encerradas entre los corchetes <
y >
, separadas por comas. Por ejemplo, he aquí un típico vector de tres componentes:
< 1.0, 3.2, -5.4578 >
Las comas separando los componentes son necesarias para prevenir que
el programa crea que el segundo componente es la expresion
3.2-5.4578
y que no hay tercer componente. Sabrás que has
olvidado poner una coma si ves un mensaje de error como "Float
expected but '>' found instead
" (se esperaba un valor de coma
flotante pero se encontró '>' en su lugar).
A veces POV-Ray requiere que especifiques en la misma expresión
valores de coma flotante y vectores. Las reglas de sintaxis de las
expresiones vectoriales permiten mezclar vectores con vectores o
vectores con valores de coma flotante, así que deberás usar comas
siempre que no sea el caso, pues se daría una ambigüedad. Por ejemplo,
<1,2,3>-4
se evalúa como una expresion mixta, donde se
resta 4 de cada componente del vector, dando como resultado
<-3,-2,-1>
. Sin embargo, al usar una coma, <1,2,3>,-4
representa un vector seguido de un valor de coma flotante.
Cada componente puede ser una expresion de coma flotante completa.
Por ejemplo, <This+3,That/3,5*Other_Thing>
es un
vector válido.
Los identificadores de vectores pueden declarase para hacer las escenas más legibles y parametrizarlas de forma que, cambiando una simple declaracion, se cambien muchos valores. Un identificador se declara de la siguiente forma:
VECTOR_DECLARATION: #declare IDENTIFIER = EXPRESSION; | #local IDENTIFIER = EXPRESSION;
Donde IDENTIFIER es el nombre del identificador, de hasta 40 caracteres de largo, y EXPRESSION es cualquier expresion válida que se evalúe a un valor de vector.
Nota: Debe haber un punto y coma detrás de la expresión en una declaración de vector. Si se omite se genera un aviso, y algunas macros pueden no funcionar correctamente. Véase la sección " #declare frente a #local" para más información acerca del alcance de los identificadores.
He aquí algunos ejemplos:
#declare Here = <1,2,3>; #declare There = <3,4,5>; #declare Jump = <Foo*2,Bar-1,Bob/3>; #declare Route = There-Here; #declare Jump = Jump+<1,2,3>;
Nota: los identificadores de vector se invocan por su nombre, sin los corchetes angulares. Como se muestra en el último ejemplo, puedes redeclarar un identificador de vector, e incluso utilizar su valor previo en la redeclaracion. Existen varios identificadores predefinidos que POV-Ray declara por ti. Mira la sección "Identificadores predefinidos de vectores" para conocer más detalles.
Los literales, identificadores y funciones de vectores pueden
combinarse para formar expresiones de la misma forma que los valores de
coma flotante. Las operaciones se realizan componente a componente. Por
ejemplo, <1,2,3> + <4,5,6>
se evalúa igual que <1+4,2+5,3+6>
o <5,7,9>
. El resto de operaciones se realizan de la
misma forma, componente a componente. Por ejemplo, (<1,2,3>
= <3,2,1>)
da como resultado <0,1,0>
ya
que sólo los componentes centrales son iguales. Hay que admitir que
esto no es tal vez demasiado útil, pero es consistente con el resto de
operaciones de vectores.
Las expresiones condicionales como (C ? A : B)
requieren que C
sea una expresion de coma flotante, pero A
y B
pueden ser expresiones vectoriales. El resultado es que
toda la expresion condicional se evalúa como un vector válido. Por
ejemplo, si tenemos los números de coma flotante Foo
y
Bar
entonces (Foo < Bar ? <1,2,3> : <5,6,7>)
se evalúa como el vector <1,2,3>
cuando Foo
es menor que Bar
, y como <5,6,7>
en
caso contrario.
Puedes usar el operador punto
para extraer un componente como un valor de coma flotante. Supón que has
desclarado previamente el identificador Spot
como vector.
Entonces, Spot.x
es un valor de coma flotante que
representa el primer componente del vector <x,y,z>
.
De forma similar, Spot.y
y Spot.z
referencian
al segundo y tercer componentes. En el caso de un vector de cuatro
componentes, puedes usar .t
para extraer el cuarto
componente. El operador punto se usa también en expresiones de color,
que se detallan más adelante.
Se puede usar una expresión con un solo valor de coma flotante para
definir un vector cuyos componentes son todos iguales. POV-Ray sabe cuándo necesita un vector con determinados componentes, asi que
promoverá el valor de coma flotante a un vector. Por ejemplo, la
sentencia scale
necesita un vector de tres componentes,
asi que si especificas scale 5
POV-Ray interpreta que
quieres decir scale <5,5,5>
, o sea, que quieres
escalar por 5 en todas las direcciones.
Las versiones de POV-Ray anteriores a la 3.0 sólo permitían este uso
de número de coma flotante como vectores de forma limitada, sólo en
sitios como scale
y turbulence
, pero ahora
puedes usar este truco en cualquier parte. Por ejemplo:
box{0,1} // lo mismo que box{<0,0,0>,<1,1,1>} sphere{0,1} // lo mismo que sphere{<0,0,0>,1}
Cuando se promociona un número de coma flotante a vector de 2, 3, 4 ó 5 componentes, todos los componentes se igualan al valor de coma
flotante. Sin embargo, cuando se promociona un vector de menos
componentes a otro de más componentes, los componentes adicionales se
rellenan con 0. Por ejemplo, si POV-Ray espera un vector 4D, al
especificar el valor 9
el resultado es <9,9,9,9>
,
pero si especificas <7,6>
el resultado es
<7,6,0,0>
.
Existen varios identificadores predefinidos de vectores. Puedes usarlos para especificar valores o para crear expresiones, pero no puedes redeclararlos para cambiar sus valores. Son los siguientes:
VECTOR_BUILT-IN_IDENT: x | y | z | t | u | v
Todos los identificadores predefinidos de vectores tienen valores fijos que nunca cambian. Se definen de forma que es como si incluyeras al principio de tus escenas el siguiente código:
#declare x = <1, 0, 0>; #declare y = <0, 1, 0>; #declare z = <0, 0, 1>; #declare t = <0, 0, 0, 1>; #declare u = <1, 0>; #declare v = <0, 1>;
Los identificadores predefinidos x
, y
, y
z
pueden hacer tus escenas mucho más legibles si los usas en
expresiones de vectores, como por ejemplo:
plane { y, 1} // El vector normal es obviamente "y". plane { <0,1,0>, 1} // Esto es lo mismo, pero mas difícil de entender. translate 5*x // Mover 5 unidades en la direccion "x". translate <5,0,0> // Lo mismo, pero menos obvio.
Una expresión como por ejemplo 5*x
, se evalúa como
5*<1,0,0>
o <5,0,0>
.
De forma similar, u
y v
pueden usarse con
los vectores 2D. Para vectores 4D debes usar x
, y
,
z
, and t
. POV-Ray promoverá x
,
y
, y z
a un vector 4D cuando éste sea necesario.
POV-Ray tiene varias funciones predefinidas para manipular números de coma flotante, vectores y cadenas. Las llamadas a las funciones consisten en el nombre de la función seguido de una lista de parámetros, separados por comas y encerrados entre paréntesis. Por ejemplo:
keyword(param1,param2)
Las siguientes son funciones que devuelven valores de tipo vector.
Toman uno o más parámetros de coma flotante, enteros, vectores o
cadenas. Supón que A
y B
son expresiones
vectoriales válidas y F
es una expresión de coma flotante.
min_extent ( OBJECT_IDENTIFIER ), max_extent (
OBJECT_IDENTIFIER )
. Las funciones min_extent
y max_extent
devuelven las coordenadas mínimas y máximas de la caja de acotacion de
un objeto previamente declarado (esquina inferior izquierda y esquina
superior derecha), permitiéndote determinar las dimensiones y
localizacion del objeto.
Nota: el funcionamiento no es perfecto, y en algunos casos (como en intersecciones y diferencias de CSG o en isosuperficies) la caja de acotación puede no representar exactamente las dimensiones reales del objeto.
Ejemplo:
#declare Sphere = sphere { <0,0,0>, 1 pigment { rgb <1,0,0> } } #declare Min = min_extent ( Sphere ); #declare Max = max_extent ( Sphere ); object { Sphere } box { Min, Max pigment { rgbf <1,1,1,0.5> } }
trace(OBJECT_IDENTIFIER, A, B, [VECTOR_IDENTIFIER])
. Esta
función te ayudará a encontrar el punto exacto en el que un rayo
intersecta con la superficie de un objeto. Traza un rayo empezando en
el punto
A
y en la dirección especificada por el vector B
.
Si el rayo toca el objeto especificado, la función devuelve las
coordenadas del punto donde el rayo intersecta con el objeto. Si no,
devuelve <0,0,0>
. Si se proporciona un cuarto parámetro en forma de un identificador de vector, se almacenará en
él
el valor de la normal en el punto de interseccion (sin incluir la
perturbacion causada por las normales de las texturas).
Nota: La única manera fiable de
determinar si ha habido intersección es comprobando que la normal
devuelta sea <0,0,0>
, ya que las intersecciones
pueden ocurrir en cualquier coordenada, incluyendo <0,0,0>
.
Ejemplo:
#declare MySphere = sphere { <0, 0, 0>, 1 } #declare Norm = <0, 0, 0>; #declare Start = <1, 1, 1>; #declare Inter= trace ( MySphere, Start, <0, 0, 0>-Start, Norm ); object { MySphere texture { pigment { rgb 1} } } #if (vlength(Norm)!=0) cylinder { Inter, Inter+Norm, .1 texture { pigment {color red 1} } } #end
vaxis_rotate(A,B,F)
Rotar F
grados A
alrededor de B
. Dadas las coordenadas x,y,z
de un punto en el espacio designado por el vector
A
,
rotar este punto alrededor de un eje arbitrario definido por el vector B
.
El ángulo de rotación se especifica en grados con el valor de coma
flotante F
. El resultado es un vector que contiene las
coordenadas x,y,z del nuevo punto.
vcross(A,B)
Producto cruzado de A
por B
.
Devuelve un vector que es el producto cruzado de dos vectores. Éste es
perpendicular a los dos vectores pasados como parámetros, y su longitud
es igual al área del paralelogramo definido por éstos. La fórmula es
la siguiente: AxB = |A| * |B| * sin(angle(A,B)) *
vector_perpendicular_unitario(A,B)
. Así, la longitud del
vector resultante es proporcional al seno del ángulo que hay entre A
y B
. Renderiza la escena animada de demostración VECT2.POV
para verlo ilustrado.
vnormalize(A)
Normaliza el vector A
.
Devuelve un vector longitud unitaria que tiene la misma dirección que A
.
La fórmula es vnormalize(A)=A/vlength(A).
Nota:vnormalize(<0,0,0>)
genera
un error.
vrotate(A,B)
Rotar A
alrededor del origen
B
grados. Dadas las coordenas x,y,z de un punto en el espacio
designado por el vector A
, rotar este punto alrededor del
origen la cantidad de grados especificada por el vector B
.
Esto es, se rotará B.x
grados alrededor del eje x
,B.y
grados alrededor del eje y
, y B.z
grados
alrededor del eje z
. El resultado es un vector que
contiene las coordenadas del nuevo punto.
vturbulence(Lambda, Omega, Octaves, A)
Vector de
turbulencia en el punto A
. Dadas las coordenadas de un
punto en el espacio designado por el vector A
, devolverá
el vector de turbulencia para ese punto basándose en los valores de lambda
,omega
y octaves
suministrados. La cantidad de turbulencia puede
controlarse multiplicando el vector de turbulencia por un múltiplo. La
frecuencia con la que cambia el vector de turbulencia se puede
controlar multiplicando A
por un múltiplo. El vector de
turbulencia devuelto por la función puede sumarse al punto A
original para obtener una versión perturbada de ese punto. Por ejemplo:
#declare MyVector = MyVector + Amount*vturbulence( 2, 0.5,
6,MyVector*Frequency );
Véase la sección "Funciones de
coma flotante" para conocer otras funciones relacionadas con los
vectores, pero que devuelven valores de coma flotante. Además de las
funciones predefinidas citadas aqui, puedes tambien definir tus propias
funciones mediante la directiva #macro
. Mira la sección "Macros definidas por el usuario"
para obetener más información.
|