POV-Ray : Newsgroups : povray.general : A bit of math Server Time: 25 Jun 2019 19:35:10 GMT
 A bit of math (Message 1 to 10 of 12)
 From: Mike Horvath Subject: A bit of math Date: 26 Feb 2018 23:03:06 Message: <5a94922a@news.povray.org>
```I have a three coordinates.

// bounding box
L3ModelBBoxMin = <-1280,-428,-960>
L3ModelBBoxMax = <1280,0,-160>

// camera location
L3Location = <2413.395250,-1636.367750,-2657.726250>

How do I determine the corner of the bounding box that is nearest the
camera? Thanks.

Mike
```
 From: Bald Eagle Subject: Re: A bit of math Date: 27 Feb 2018 01:30:01 Message:
```Mike Horvath <mik### [at] gmailcom> wrote:
> I have a three coordinates.
>
> // bounding box
> L3ModelBBoxMin = <-1280,-428,-960>
> L3ModelBBoxMax = <1280,0,-160>
>
> // camera location
> L3Location = <2413.395250,-1636.367750,-2657.726250>
>
>
> How do I determine the corner of the bounding box that is nearest the
> camera? Thanks.
>
>
> Mike

Define the corners you want to test, and calculate the vlength between the
corners and the camera location.   Then use min().
```
 From: Mike Horvath Subject: Re: A bit of math Date: 27 Feb 2018 01:50:30 Message: <5a94b966\$1@news.povray.org>
```On 2/26/2018 8:26 PM, Bald Eagle wrote:
> Mike Horvath <mik### [at] gmailcom> wrote:
>> I have a three coordinates.
>>
>> // bounding box
>> L3ModelBBoxMin = <-1280,-428,-960>
>> L3ModelBBoxMax = <1280,0,-160>
>>
>> // camera location
>> L3Location = <2413.395250,-1636.367750,-2657.726250>
>>
>>
>> How do I determine the corner of the bounding box that is nearest the
>> camera? Thanks.
>>
>>
>> Mike
>
> Define the corners you want to test, and calculate the vlength between the
> corners and the camera location.   Then use min().
>
>

I get an error when I try to set the value of a vector's x-coordinate.

#local NearCorner.x = BBoxMin.x;

What is the correct way to set this coordinate?

Mike
```
 From: Bald Eagle Subject: Re: A bit of math Date: 27 Feb 2018 02:20:01 Message:
```Mike Horvath <mik### [at] gmailcom> wrote:

> I get an error when I try to set the value of a vector's x-coordinate.
>
>  #local NearCorner.x = BBoxMin.x;
>
> What is the correct way to set this coordinate?

#local NearCorner = <BBoxMin.x, BBoxMin.y, BBoxMin.z>;

or

#local NearCorner = NearCorner + <BBoxMin.x, 0, 0>;

You can USE the .x you just can't declare it.
```
 From: clipka Subject: Re: A bit of math Date: 27 Feb 2018 10:46:33 Message: <5a953709\$1@news.povray.org>
```Am 27.02.2018 um 03:15 schrieb Bald Eagle:
> Mike Horvath <mik### [at] gmailcom> wrote:
>
>> I get an error when I try to set the value of a vector's x-coordinate.
>>
>>  #local NearCorner.x = BBoxMin.x;
>>
>> What is the correct way to set this coordinate?
>
> #local NearCorner = <BBoxMin.x, BBoxMin.y, BBoxMin.z>;
>
> or
>
> #local NearCorner = NearCorner + <BBoxMin.x, 0, 0>;

Neither will do what Mike presumably expects to happen; the former would
set all coordinates of NearCorner to those from BBoxMin, while the
latter would /increase/ NearCorner.x by BBoxMin.x rather than replace
the value.

To really just replace NearCorner's x coordinate, use:

#local NearCorner = <BBoxMin.x, NearCorner.y, NearCorner.z>;

or:

#local NearCorner = NearCorner*<0,1,1> + BBoxMin*<1,0,0>;
```
 From: clipka Subject: Re: A bit of math Date: 27 Feb 2018 10:48:51 Message: <5a953793\$1@news.povray.org>
```Am 27.02.2018 um 02:51 schrieb Mike Horvath:

> I get an error when I try to set the value of a vector's x-coordinate.
>
> Â Â Â Â #local NearCorner.x = BBoxMin.x;
>
> What is the correct way to set this coordinate?

Technically you can't just overwrite a single coordinate of a vector.
You'll have to overwrite the entire vector; any coordinate you want to
stay the same will have to be explicitly taken from the vector's old value.

See my other post for examples how to achieve this.
```
 From: clipka Subject: Re: A bit of math Date: 27 Feb 2018 11:57:22 Message: <5a9547a2\$1@news.povray.org>
```Am 27.02.2018 um 02:26 schrieb Bald Eagle:
> Mike Horvath <mik### [at] gmailcom> wrote:
>> I have a three coordinates.
>>
>> // bounding box
>> L3ModelBBoxMin = <-1280,-428,-960>
>> L3ModelBBoxMax = <1280,0,-160>
>>
>> // camera location
>> L3Location = <2413.395250,-1636.367750,-2657.726250>
>>
>>
>> How do I determine the corner of the bounding box that is nearest the
>> camera? Thanks.
>>
>>
>> Mike
>
> Define the corners you want to test, and calculate the vlength between the
> corners and the camera location.   Then use min().

That approach requires 8 vector differences, 8 invocations of vlength
(which is a comparatively expensive operation as it needs to compute a
square root), and an 8-parameter invocations of min(), for a total of 24
operations (8 of which are computationally expensive).

An alternative exists that requires 2 vector differences, 2
coordinate-wise vector multiplications, 3 two-parameter invocations of
min(), 1 sum of three vectors, and 1 square root, for a total of just 9
operations (only 1 of which is computationally expensive).

The basic approach exploits the fact that the bounding box is
axis-aligned, and goes as follows:

(1) For each axis, compute the absolute distance between the camera and
both the nearest and the farthest side of the bounding box.

(2) For each axis, compute the smaller of the two absolute distances.

(3) Compute the length of the vector given by the three smallest
absolute distances.

Naively, this would be:

(1)
#declare DistAX = abs(L3ModelBBoxMin.x - L3Location.x);
#declare DistAY = abs(L3ModelBBoxMin.y - L3Location.y);
#declare DistAZ = abs(L3ModelBBoxMin.z - L3Location.z);
#declare DistBX = abs(L3ModelBBoxMax.x - L3Location.x);
#declare DistBY = abs(L3ModelBBoxMax.y - L3Location.y);
#declare DistBZ = abs(L3ModelBBoxMax.z - L3Location.z);
(2)
#declare DistX = min(DistAX,DistBX);
#declare DistY = min(DistAY,DistBY);
#declare DistZ = min(DistAZ,DistBZ);
(3)
#declare Dist = vlength(<DistX,DistY,DistZ>);

Even in this straightforward form the algorithm has just 16 operations,
only one of which is is a computationally expensive vlength operation.

Better yet, this algorithm provides room for further optimization.

The first step may be a bit counter-intuitive, as we'll re-write step
(3) using more primitive operations:

(3a)
#declare SqrDistX = DistX*DistX;
#declare SqrDistY = DistY*DistY;
#declare SqrDistZ = DistZ*DistZ;
(3b)
#declare SqrDist = SqrDistX+SqrDistY+SqrDistZ;
#declare Dist = sqrt(SqrDist);

Now note that since DistX, DistY and DistZ are positive values, it
doesn't matter whether we compute the smaller of each of them before or
after squaring, allowing us to re-arrange steps (2) and (3a) as follows:

(3a)
#declare SqrDistAX = DistAX*DistAX;
#declare SqrDistAY = DistAY*DistAY;
#declare SqrDistAZ = DistAZ*DistAZ;
#declare SqrDistBX = DistBX*DistBX;
#declare SqrDistBY = DistBY*DistBY;
#declare SqrDistBZ = DistBZ*DistBZ;
(2)
#declare SqrDistX = min(SqrDistAX,SqrDistBX);
#declare SqrDistY = min(SqrDistAY,SqrDistBY);
#declare SqrDistZ = min(SqrDistAZ,SqrDistBZ);

Now note that a distance squared is always positive no matter the sign
of the input values, so it doesn't matter whether we compute the
absolute in step (1), allowing us to rewrite it as follows:

(1)
#declare DistAX = L3ModelBBoxMin.x - L3Location.x;
#declare DistAY = L3ModelBBoxMin.y - L3Location.y;
#declare DistAZ = L3ModelBBoxMin.z - L3Location.z;
#declare DistBX = L3ModelBBoxMax.x - L3Location.x;
#declare DistBY = L3ModelBBoxMax.y - L3Location.y;
#declare DistBZ = L3ModelBBoxMax.z - L3Location.z;

Now note that since steps (1) and (3a) are effectively coordinate-wise
operations for which corresponding vector operations are available, we
can yet again rewrite the code one last time, leaving us with the
following compact form:

(1)
#declare DistA = L3ModelBBoxMin - L3Location;
#declare DistB = L3ModelBBoxMax - L3Location;
(3a)
#declare SqrDistA = DistA*DistA;
#declare SqrDistB = DistB*DistB;
(2)
#declare SqrDistX = min(SqrDistA.x,SqrDistB.x);
#declare SqrDistY = min(SqrDistA.y,SqrDistB.y);
#declare SqrDistZ = min(SqrDistA.z,SqrDistB.z);
(3b)
#declare SqrDist = SqrDistX+SqrDistY+SqrDistZ;
#declare Dist = sqrt(SqrDist);

As you can see, this leaves us with just 9 operations (or 10 if you are
nitpicky and count the three-vector sum as 2 two-vector sums), and the
only computationally expensive one is 1 square root.
```
 From: Bald Eagle Subject: Re: A bit of math Date: 27 Feb 2018 14:05:01 Message:
```clipka <ano### [at] anonymousorg> wrote:

> Neither will do what Mike presumably expects to happen;

Right - It was late, and I just wanted to put it out there quickly, hoping he
could puzzle the rest out once the .x component confusion was resolved.
(I was proceeding from the assumption that "we'd" be starting from <0, 0, 0>.)

Way to code the whole thing out.  Twice.  <clap>

Excellent post about the computational expense of the two different methods!
:)
I'll give that a thorough reading when I get the chance.
Stuff like that is gold.
```
 From: Gergely Szaktilla Subject: Re: A bit of math Date: 27 Feb 2018 14:52:57 Message: <5a9570c9\$1@news.povray.org>
```Am 27.02.2018 um 15:02 schrieb Bald Eagle:
> ... I'll give that a thorough reading when I get the chance.
> Stuff like that is gold.

I often find gold of this kind when digging in online dirt. It is worth
digging.

Gregor
```
 From: dick balaska Subject: Re: A bit of math Date: 27 Feb 2018 20:06:50 Message: <5a95ba5a\$1@news.povray.org>
```On 02/27/2018 09:02 AM, Bald Eagle wrote:
> Stuff like that is gold.
>
>

This is brilliant. Such a basic construct that is not in my use of the
language.

> #local NearCorner = NearCorner*<0,1,1> + BBoxMin*<1,0,0>;

I do BBoxMin*x a lot, but I've never thought of

#declare yz=<0,1,1>;
#local NearCorner = NearCorner*yz + BBoxMin*x;

I find this cleaner (if a tad slower) than the verbose method I use
> #local NearCorner = <BBoxMin.x, NearCorner.y, NearCorner.z>;

--
dik
Rendered 920576 of 921600 pixels (99%)
```