POV-Ray : Newsgroups : povray.pov4.discussion.general : POV-Ray 4 SDL: Some concrete proposal : Re: POV-Ray 4 SDL: Some concrete proposal Server Time
23 Feb 2024 18:03:47 EST (-0500)
  Re: POV-Ray 4 SDL: Some concrete proposal  
From: Lukas Winter
Date: 13 Apr 2009 17:40:40
Message: <49e3b158$1@news.povray.org>
Am Mon, 13 Apr 2009 15:57:54 -0400 schrieb clipka:
> - "sphere{...}" is an expression returning a sphere. As a matter of
> fact, it is an expression taking a "prototype" object (in this case
> *the* prototype sphere) and a "modification block" describing how the
> desired object differs from that prototype. (Similarly,
> "MainSphere{...}" takes MainSphere as a prototype to build yet another
> one.) Within that modification block, the newly created object is the
> current one.

Prototyping is a great concept and I'd love to see it in POV 4.

> - "rotate(...) and translate()" are functions both returning a
> transformation; as an expression-only statement, these transformations
> are applied to the current object (which hopefully knows what to do with
> them).

I find this inconsistent. Why is rotate a function and sphere is not a 
function? I think rotate and translate should be expressions returning a 
transformation and use curly brackets as well. They could return identity 
transformations as a default. Ultimately I dream of foing something like 
this:

/*let's define the prototype of a rotation around a certain axis...*/
rotate_around_axis = rotate
{
  input axis = #<1, 0, 0>; /*default value*/
  input amount = 0; /*default value*/
  rotation_vector = /*whatever it takes to calculate this rotation*/;
};

/*let's use it!*/
sphere
{
  radius = 20;
  center = <100, 0, 0>;
  transformation *= rotate_around_axis
    {
      axis = <.5, .5, .5>;
      amount = 30;
      /*the actual transformation is automagically performed according to 
the calculations made in the definition of rotate_around_axis.*/
    };
};

Which means: lazy evaluation of prototype definitions! I chose = instead 
of : because of consistency and *= means composition of two 
transformation and writing the result back to the lhs. Simply putting a 
transformation inside a modification block does not work for me (it works 
in POV 3 because it does not use object properties). There should be 
something to signify that you are _applying_ this transformation.

> 
> - "modify MainSphere{...}" is a statement taking a "modification block"
> as well, in this case describing how the object itself is to be changed.
> 
I'm pretty sure we don't need modify. Just use

MainSphere = MainSphere
{
  radius = NewRadiusForMainSphere
};

This should be the same. We're just using a variable as the prototype for 
itself, clever, huh? ;)

> - adding "as <Name>" to an expression stores the value of that
> expression for later use, serving as an "on-the-fly assignment"

I agree with Warp here, a = would be more consistent.

> - variables are global by default when assigned; in expressions, local
> variables take precedence. Local variables are visible only in the code
> block in which they are used (in case of the "R1" variable, this is the
> enclosing for loop)

> - the current object's properties are assigned to using "<Name>:
> <Value>" to avoid mixups with local and global variables

> - the current object's properties can also be accessed using ".<Name>";
> note that this also allows for ".<Name> = <Value>", but using so makes
> the code ugly as it optically disrupts indentation ;)

You mean "<Name> : <Value>" is shorthand for ".<Name> = <Value>"? I'd 
rather make "::<Name>" access a global variable and "<Name>" always 
access the most local one, like in C++. So we'd get rid of all those 
different notations for assigning variables.

So, here's my version of your example ;)

include "colors.inc";

SphereCenter = <0,1,0>;

MainSphere = sphere {
  center = SphereCenter;
  radius = 1;
  ::SphereRadius = radius; //if you _really_ want to create this global 
variable
  texture = texture
  {
    /*Local texture overrides global texture but that's no problem because
    the prototype already has a default texture.*/
    pigment { color = <1,0,0> }
  };
};

scene += MainSphere; /*or whatever symbol is reserved for "append"*/

scene += plane {
  normal = <1,1,0>;
  offset = SphereRadius;
  transformation *= translate{offset = SphereCenter}; /*Probably too 
verbose...*/
  texture = texture {
    pigment = pigment { color = <0,1,0> };
  };
};

gen = random_generator
{
  seed = 12345;
}

/*I'm not sure whether I like this syntax or not...*/
for I = 1 to 100 do
  scene += sphere {
    radius = 0.1;
    center = y * SphereRadius;
    R1 = gen.rand();
    transformation *= rotate{ radians = x * R1 * 2 * pi; }
                    * rotate{ degrees = y * gen.rand() * 2 * 360;};  
    texture = texture {
      pigment = pigment { color = <0,0,R1> };
    };
  };
end;

MainSphere = MainSphere {
  radius = 0.9;
};
/*Do we modify what was already added to the scene? Then we can't clone 
objects this way! If we don't, we can't change objects that are already 
in the scene! Note that the "modify" keyword is no solution to that 
problem.*/

scene += MainSphere {
  center = center + y*0.5;
};

/*Here I think the intention here was to clone MainSphere.*/

debug(MainSphere.center);
debug(MainSphere["center"]);

Ah, sorry for taking your nice syntax apart and transforming it to 
something completely different. I just couldn't resist. I think you're on 
the right track, though!


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.