|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
I would like to blob together several box shapes in an isosurface. The size
and transformations of each box will be output from Moray to help me
visualize where everything is.
The following approach seems to work so far.
Only one shape is used so far. Additional shapes will use an array, like in
sx (start x), and a loop. Shear not add yet. Bounding box not calculated.
My question:
Is there a better way to add the transformations to the individual shapes in
the isosurface.
//start code
camera {
location <-0.5, 2.0, -3.0>
look_at <0.5, 0.5, 0.0>
right x*image_width/image_height
}
light_source {
0*x
color rgb <1,1,1>
translate <-20, 40, -20>
}
#declare sx=array[4]{0,0,0,0}; // start
#declare sy=0;
#declare sz=0;
#declare fx=1; // finish
#declare fy=1;
#declare fz=1;
#declare length_x=(fx-sx[0]);
#declare length_y=(fx-sy);
#declare length_z=(fx-sz);
#declare scx=1; // scale
#declare scy=1;
#declare scz=1;
#declare shxy=0; // shear
#declare shxz=0;
#declare shyx=0;
#declare shyz=0;
#declare shzx=0;
#declare shzy=0;
#declare rx=20; // rotate
#declare ry=0;
#declare rz=0;
#declare tx=0; // translate
#declare ty=0;
#declare tz=0;
#declare f_box = function (x,y,z) {
max(
(abs(x-length_x/2+sx[0])-abs(length_x/2)),
(abs(y-length_y/2+sy)-abs(length_y/2)),
(abs(z-length_z/2+sz)-abs(length_z/2))
)
};
#declare f_scale = function (x,y,z) {f_box(x/scx,y/scy,z/scz)};
#declare f_rotate_x = function (x,y,z) {f_scale (x
,z*sin(radians(rx)) + y*cos(radians(rx)) ,z*cos(radians(rx)) -
y*sin(radians(rx)))};
#declare f_rotate_y = function (x,y,z)
{f_rotate_x(x*cos(radians(ry)) - z*sin(radians(ry)) ,y ,x*sin(radians(ry)) +
z*cos(radians(ry)))};
#declare f_rotate_z = function (x,y,z) {f_rotate_y(x*cos(radians(rz))
+ y*sin(radians(rz)) ,-x*sin(radians(rz)) + y*cos(radians(rz)),z)};
#declare f_translate = function (x,y,z) {f_rotate_z(x-tx,y-ty,z-tz)};
#declare f_isosurface_box = function (x,y,z) {f_translate(x,y,z)};
isosurface {
function { f_isosurface_box(x,y,z) }
contained_by { box { -5, 5 } }
texture { pigment {color red 1} finish{ambient 0.2} }
}
// end code
Stephen
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
In article <3f967141@news.povray.org>,
"StephenS" <ssh### [at] echelonca> wrote:
> Is there a better way to add the transformations to the individual shapes in
> the isosurface.
Well, there's a better way of representing the transformations in the
first place. Declare a transform function with the inverse of the
transforms:
#declare TransFn =
function {
transform {
...your transforms...
invert
}
}
isosurface {
function {
f_isosurface_box(
TransFn(x, y, z).x,
TransFn(x, y, z).y,
TransFn(x, y, z).z
)
}
...
Of course, this is less efficient than it could be, since you can't
declare variables or handle vectors, but it's certainly easier to handle
and more efficient at handling lots of transformations. You could write
macros to create separate functions for the x, y, and z coordinates
which might be more efficient...
#macro XTransFn(Trans)
#local TransFn = function {transform {Trans}}
#local C0 = TransFn(0, 0, 0);
#local CX = TransFn(1, 0, 0) - C0;
#local CY = TransFn(0, 1, 0) - C0;
#local CZ = TransFn(0, 0, 1) - C0;
function {x*CX.x + y*CY.x + z*CZ.x + C0.x}
#end
And similarly for y and z...a smarter macro could remove zero terms to
speed calculation. This macro would be used like this:
#declare f_RotateX = XTransFn(transform {rotate ...})
--
Christopher James Huff <cja### [at] earthlinknet>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: chr### [at] tagpovrayorg
http://tag.povray.org/
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
...
> Well, there's a better way of representing the transformations in the
> first place. Declare a transform function with the inverse of the
> transforms:
>
> #declare TransFn =
> function {
> transform {
> ...your transforms...
> invert
> }
> }
>
> isosurface {
> function {
> f_isosurface_box(
> TransFn(x, y, z).x,
> TransFn(x, y, z).y,
> TransFn(x, y, z).z
> )
> }
> ...
>
> Of course, this is less efficient than it could be, since you can't
> declare variables or handle vectors, but it's certainly easier to handle
> and more efficient at handling lots of transformations. You could write
> macros to create separate functions for the x, y, and z coordinates
> which might be more efficient...
>
> #macro XTransFn(Trans)
> #local TransFn = function {transform {Trans}}
> #local C0 = TransFn(0, 0, 0);
> #local CX = TransFn(1, 0, 0) - C0;
> #local CY = TransFn(0, 1, 0) - C0;
> #local CZ = TransFn(0, 0, 1) - C0;
> function {x*CX.x + y*CY.x + z*CZ.x + C0.x}
> #end
>
> And similarly for y and z...a smarter macro could remove zero terms to
> speed calculation. This macro would be used like this:
>
> #declare f_RotateX = XTransFn(transform {rotate ...})
>
...
Thanks for your reply. I don't completly understand all that you sugested,
but it gives me a few things to look into. Will have to play with the code
for awhile :-)
Stephen
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
In article <3f99aa40$1@news.povray.org>,
"StephenS" <ssh### [at] echelonca> wrote:
> Thanks for your reply. I don't completly understand all that you sugested,
> but it gives me a few things to look into. Will have to play with the code
> for awhile :-)
Here's a short explanation of the macro:
#macro TransFn(Comp, Trans)
#local TmpTransFn = function {transform {Trans}}
#local C0 = TmpTransFn(0, 0, 0);
#local CX = TmpTransFn(1, 0, 0) - C0;
#local CY = TmpTransFn(0, 1, 0) - C0;
#local CZ = TmpTransFn(0, 0, 1) - C0;
#switch(Comp)
#case(0)
#local X = CX.x;
#local Y = CY.x;
#local Z = CZ.x;
#local T = C0.x;
#break
#case(1)
#local X = CX.y;
#local Y = CY.y;
#local Z = CZ.y;
#local T = C0.y;
#break
#case(2)
#local X = CX.z;
#local Y = CY.z;
#local Z = CZ.z;
#local T = C0.z;
#break
#end
function {x*X + y*Y + z*Z + T}
#end
POV-Ray transformations are stored in 3x4 matrices, basically 3x3
matrices with translation columns tacked on. Points are transformed by
the matrix like this:
xOut = m11*x + m12*y + m13*z + m14
yOut = m21*x + m22*y + m23*z + m24
yOut = m31*x + m32*y + m33*z + m34
Transforming < 0, 0, 0> gives the translation column alone. Transforming
< 1, 0, 0>, < 0, 1, 0>, and < 0, 0, 1> and subtracting the translation
give the first three columns. Then a function is created with the matrix
elements of the desired row.
Unfortunately, I've tested it, and this is actually slower than
evaluating the transform function directly. The test took 28 seconds
with the transform function, and 32 with the functions produced with
this macro (7 seconds with no transformations). Removing multiplications
by 1 and zero terms, I ended up with transformation functions that
produced an isosurface that rendered in 23 seconds, but this will only
happen in certain limited cases, so it really isn't worth the effort to
implement this optimization. Here's a considerably simpler macro which
is also easier to use:
#macro TransformFn(Func, Trans)
#ifdef(f_Trans)
#undef f_Trans
#end
#local f_Trans = function {transform {Trans}}
#local Res = function {Func(f_Trans(x, y, z).x, f_Trans(x, y, z).y,
f_Trans(x, y, z).z)}
Res(x, y, z)
#end
#local Trans = transform {scale < 1, 3, 1> translate -y*1 inverse}
isosurface {
function {1 - TransformFn(f_r, Trans)}
--
Christopher James Huff <cja### [at] earthlinknet>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: chr### [at] tagpovrayorg
http://tag.povray.org/
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Christopher James Huff wrote
...
> Here's a considerably simpler macro which
> is also easier to use:
...
This is much closer to what I was hoping for when I started :-)
I now have the following code.
-box declared with start/finish points and/or scale/translate.
-additional shapes can be added. Shapes that can be easily represented with
a wireframe interest me the most.
-scale and shear have been kept separate for ease of reading.
-bounded_by not calculated from objects used, user inputs values.
// start code
camera {
location <-0.5, 2.0, -3.0>
look_at <0.5, 0.5, 0.0>
right x*image_width/image_height
}
light_source {
0*x
color rgb <1.5,1.5,1.5>
translate <-15, 30, -20>
}
light_source {
0*x
color rgb <.5,.5,.5>
translate <0, -30, -20>
}
light_source {
0*x
color rgb <.5,.5,.5>
translate <20, -5, -20>
}
// possible output from external program
#declare sx=array[4]{0,0,.2,0}; // start
#declare sy=array[4]{0,0,0,0};
#declare sz=array[4]{0,0,0,0};
#declare fx=array[4]{1,.1,1,1}; // finish
#declare fy=array[4]{1,1,1,1};
#declare fz=array[4]{1,1,1,1};
#declare scx=array[4]{1,1,1,1}; // scale
#declare scy=array[4]{1,1,1,1};
#declare scz=array[4]{1,1,1,1};
#declare shxy=array[4]{0,0,0,-.2}; // shear
#declare shxz=array[4]{0,0,0,0};
#declare shyx=array[4]{0,0,0,0};
#declare shyz=array[4]{0,0,0,0};
#declare shzx=array[4]{0,0,0,0};
#declare shzy=array[4]{0,0,0,0};
#declare rx=array[4]{0,0,0,0}; // rotate
#declare ry=array[4]{0,0,0,0};
#declare rz=array[4]{0,-10,0,0};
#declare tx=array[4]{0,.5,-.2,-.6}; // translate
#declare ty=array[4]{0,.5,0,.6};
#declare tz=array[4]{0,-.5,.5,.5};
#declare ob=array[4]{1,1,2,1}
#local Blob_threshold=.000001;
#local maxnum=4; // change from 1 - 4
// Pov code to make blobbed isosurface object
#macro m_object(num)
#switch(ob[num])
#case(1) // box
function {
max(
(abs(x-(fx[num]-sx[num])/2-sx[num])-abs(fx[num]-sx[num])/2),
(abs(y-(fy[num]-sy[num])/2-sy[num])-abs(fy[num]-sy[num])/2),
(abs(z-(fz[num]-sz[num])/2-sz[num])-abs(fz[num]-sz[num])/2)
)
}
#break
#case(2) // sphere
function {
pow(x,2) + pow(y,2) + pow(z,2) - pow(sx[num],2)
}
#break
#end // switch
#end // macro
#macro TransformFn(Func, Trans)
#ifdef(f_Trans)
#undef f_Trans
#end
#local f_Trans = function {transform {Trans}}
#local Res = function {Func(f_Trans(x, y, z).x,
f_Trans(x, y, z).y,
f_Trans(x, y, z).z)}
Res(x, y, z)
#end
isosurface {
#local num=0;
function {
(1+Blob_threshold)
#while (num<maxnum)
#local Trans =
transform {
scale < scx [num], scy [num], scz [num]>
matrix < 1 , shyx[num], shzx[num], // shear
shxy[num], 1 , shzy[num],
shxz[num], shyz[num], 1 ,
0 , 0 , 0 >
rotate < rx [num], ry [num], rz [num]>
translate < tx [num], ty [num], tz [num]>
inverse};
-pow(Blob_threshold,TransformFn(m_object(num), Trans))
#declare num=num+1;
#end // while
}
contained_by { box { -1.6, 1.6 } }
max_gradient (14.1)
texture { pigment {color red 1} finish{ambient 0.2} }
}
// end code
My question:
Is there a better way to organize my isosurface and macros?
Stephen
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|