POV-Ray : Newsgroups : povray.text.scene-files : Source code for bevelled box Server Time
1 Nov 2024 11:17:02 EDT (-0400)
  Source code for bevelled box (Message 1 to 7 of 7)  
From: Tor Olav Kristensen
Subject: Source code for bevelled box
Date: 10 Oct 2000 20:14:07
Message: <39E3AFCA.B8FB8283@online.no>
Here's my "Total Overkill" code for calculating position of corners for
a bevelled box.

This is a reply to  Greg M. Johnson's post "truncated cubes" to
povray.binaries.images  6. October:

news://news.povray.org/39DDC1B9.8637A48C%40my-dejanews.com
news://news.povray.org/39E1B9BD.60A199EA%40my-dejanews.com


Note: This code does not bevel any convex shape of plane intersections.
(But some of the macros below could be useful when writing code that
does this.)


Tor Olav

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2000 by Tor Olav Kristensen
// mailto:tor### [at] hotmailcom
// http://www.crosswinds.net/~tok/tokrays.html
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.1;

#include "colors.inc"

global_settings { ambient_light color White }

#declare infinite = 100000;
#declare nothing = 1/infinite;
#declare less = -nothing;
#declare more = +nothing;
//#declare smaller = 1 + less;
//#declare bigger  = 1 + more;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// The macros that do the "dirty" work


// Scalar Triple Product of 3 vectors
#macro S3Prod(v1, v2, v3)

  vdot(v1, vcross(v2, v3))

#end // macro S3Prod


// Find the intersection of 3 planes
#macro pl2pl2pl(pPlane1, vPlane1, pPlane2, vPlane2, pPlane3, vPlane3)

  ((vdot(pPlane1, vPlane1)*vcross(vPlane2, vPlane3) +
    vdot(pPlane2, vPlane2)*vcross(vPlane3, vPlane1) +
    vdot(pPlane3, vPlane3)*vcross(vPlane1, vPlane2))/
    S3Prod(vPlane1, vPlane2, vPlane3))

#end // macro pl2pl2pl


// Make a convex shape by intersection of planes
#macro MakeConvex(PlaneNormals, PlaneDistances)

  #local NrOfPlanes = dimension_size(PlaneNormals, 1);
  #local PlaneCnt = 0;
  intersection {
    #while (PlaneCnt < NrOfPlanes)
      plane { PlaneNormals[PlaneCnt], PlaneDistances[PlaneCnt] }
      #local PlaneCnt = PlaneCnt + 1;
    #end // while
  }

#end // macro MakeConvex


// Determine if there are any planes between a point and origo
#macro PlaneUnder(p0, PlaneNormals, PlaneDistances)

  #local NrOfPlanes = dimension_size(PlaneNormals, 1);
  #local PointDist = vlength(p0);
  #local CloserPlane = false;
  #local Cnt = 0;
  #while(Cnt < NrOfPlanes & !CloserPlane)
    #local PlaneDist = PlaneDistances[Cnt];
    #if (PlaneDist < PointDist)
      #local vPlane = vnormalize(PlaneNormals[Cnt]);
      #local DOT = vdot(p0, vPlane);
      #if (DOT > 0)
        #local CloserPlane = (PlaneDist + more < DOT);
      #end // if
    #end // if
    #local Cnt = Cnt + 1;
  #end // while

  CloserPlane

#end // macro PlaneUnder


// Find all possible corners at the intersections of every triple
// of non-parallel planes and test each of them to see if they are
// "false" (i.e. with a plane "below"). Write all the real ones to
// a file. Write to another file which 3 planes each of the "real"
// corners are in the intersection of. Return the number of "real"
// corners found
#macro WriteCorners(PlaneNormals, PlaneDistances,
                    MapFileName, CornerFileName)

  #local NrOfPlanes = dimension_size(PlaneNormals, 1);
  #fopen MapFile MapFileName write
  #fopen CornerFile CornerFileName write
  #write (CornerFile, " \n")
  #write (MapFile, " \n")
  #local CornerCnt = 0;
  #local PlaneCnt0 = 0;
  #while (PlaneCnt0 < NrOfPlanes - 2)
    #local vPl0 = PlaneNormals[PlaneCnt0];
    #local PlaneCnt1 = PlaneCnt0 + 1;
    #while (PlaneCnt1 < NrOfPlanes - 1)
      #local vPl1 = PlaneNormals[PlaneCnt1];
      #local PlaneCnt2 = PlaneCnt1 + 1;
      #while (PlaneCnt2 < NrOfPlanes)
        #local vPl2 = PlaneNormals[PlaneCnt2];
        #if (S3Prod(vPl0, vPl1, vPl2) != 0)
          #local pPl0 = PlaneDistances[PlaneCnt0]*vnormalize(vPl0);
          #local pPl1 = PlaneDistances[PlaneCnt1]*vnormalize(vPl1);
          #local pPl2 = PlaneDistances[PlaneCnt2]*vnormalize(vPl2);
          #local pCommon = pl2pl2pl(pPl0, vPl0, pPl1, vPl1, pPl2, vPl2);

          #if (!PlaneUnder(pCommon, PlaneNormals, PlaneDistances))
            #write (CornerFile, pCommon, ",\n")
            #write (MapFile, <PlaneCnt0, PlaneCnt1, PlaneCnt2>, ",\n")
            #local CornerCnt = CornerCnt + 1;
          #end // if
        #end // if
        #local PlaneCnt2 = PlaneCnt2 + 1;
      #end // while
      #local PlaneCnt1 = PlaneCnt1 + 1;
    #end // while
    #local PlaneCnt0 = PlaneCnt0 + 1;
  #end // while
  #fclose MapFile
  #fclose CornerFile

  CornerCnt

#end // macro WriteCorners



// Read numbers or vectors from a text file into an array
// Note: There's no check for nr of items in the file or the size of
// the array.
#macro ReadFileToArray(FileName, Array)

  #local NrOfItems = dimension_size(Array, 1);
  #fopen ReadFile FileName read
  #local Cnt = 0;
  #while (Cnt < NrOfItems)
    #read (ReadFile, Temp)
    #declare Array[Cnt] = Temp;
    #local Cnt = Cnt + 1;
  #end // while
  #fclose ReadFile

#end // macro ReadFileToArray



// Output the components of a 3D vector to the debug window
#macro PrintVector(v0)

    #debug "<"
    #debug str(v0.x, 9, 6)
    #debug ", "
    #debug str(v0.y, 9, 6)
    #debug ", "
    #debug str(v0.z, 9, 6)
    #debug ">"

#end // macro PrintVector


// Put spheres at every point in the array
#macro PlotCorners(CornerArray, Radius)

  #local NrOfCorners = dimension_size(CornerArray, 1);
  union {
    #local Cnt = 0;
    #while (Cnt < NrOfCorners)
      sphere { CornerArray[Cnt], Radius }
      #local Cnt = Cnt + 1;
    #end // while
  }

#end // macro PlotCorners


// Output the data for the planes given by the two arrays to the
// debug window
#macro ListPlanes(PlaneNormals, PlaneDistances)

  #debug "\n"
  #local NrOfPlanes = dimension_size(PlaneNormals, 1);
  #local Cnt = 0;
  #while (Cnt < NrOfPlanes)
    #debug "\nPlane No. "
    #debug str(Cnt, 3, 0)
    #debug "  Normal vector: "
    PrintVector(PlaneNormals[Cnt])
    #debug "  Distance from origo: "
    #debug str(PlaneDistances[Cnt], 0, -1)
    #local Cnt = Cnt + 1;
  #end // while
  #debug "\n"

#end // macro ListPlanes


// Output the data for the corners given in the two arrays to the
// debug window
#macro ListCorners(CornerMapArray, CornerArray)

  #debug "\n"
  #local NrOfCorners = dimension_size(CornerMapArray, 1);
  #local Cnt = 0;
  #while (Cnt < NrOfCorners)
    #local CI = CornerMapArray[Cnt];
    #debug "\nCorner No. "
    #debug str(Cnt, 4, 0)
    #debug ":  Plane "
    #debug str(CI.x, 3, 0)
    #debug " & Plane "
    #debug str(CI.y, 3, 0)
    #debug " & Plane "
    #debug str(CI.z, 3, 0)
    #debug "  Common point: "
    PrintVector(CornerArray[Cnt])
    #local Cnt = Cnt + 1;
  #end // while
  #debug "\n"

#end // macro ListCorners

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Parameters for the bevelled box

#declare L = 3; // Length
#declare H = 1; // Height
#declare W = 2; // Width

#declare BevelSize = 0.1;
//#declare BevelSize = BevelSize/sqrt(2);
#declare SphereRadius = 0.03;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Initialize arrays for the needed planes

#declare NrOfPlanes = 18;

#declare ArraysOfNormals =
array[NrOfPlanes]{
   +x,   +y,   +z,
   -x,   -y,   -z,
  +x+y, +x+z, +y+z,
  +x-y, +x-z, +y-z,
  -x+y, -x+z, -y+z,
  -x-y, -x-z, -y-z
}

#declare ArrayOfDistances = array[NrOfPlanes]

#declare Cnt = 0;
#while (Cnt < NrOfPlanes)
  #declare vN = ArraysOfNormals[Cnt];
  #declare ArrayOfDistances[Cnt] =
    vdot(vnormalize(vN), vN*<L, H, W>)/2 - (Cnt < 6 ? 0 : BevelSize);
  #declare Cnt = Cnt + 1;
#end // while

ListPlanes(ArraysOfNormals, ArrayOfDistances)

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Call the macros

#declare NrOfCorners = WriteCorners(
                         ArraysOfNormals,
                         ArrayOfDistances,
                         "PlaneTriples.txt",
                         "Corners.txt"
                       );

#declare ArrayMapOfCorners = array[NrOfCorners]
#declare ArrayOfCorners    = array[NrOfCorners]

ReadFileToArray("PlaneTriples.txt", ArrayMapOfCorners)
ReadFileToArray("Corners.txt", ArrayOfCorners)

ListCorners(ArrayMapOfCorners, ArrayOfCorners)


object {
  MakeConvex(ArraysOfNormals, ArrayOfDistances)
  pigment { color Grey }
}

object {
  PlotCorners(ArrayOfCorners, SphereRadius)
  pigment { color Red }
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

background { color Blue/2 }

light_source { <4, 3, -5>*10 color 1.2*White }

camera {
  location <2, 1, -2>*1.2
  look_at <0, 0, 0>
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

From: John VanSickle
Subject: Re: Source code for bevelled box
Date: 10 Oct 2000 21:19:13
Message: <39E3C12C.29AA9B11@erols.com>
Tor Olav Kristensen wrote:
> 
> Here's my "Total Overkill" code for calculating position of corners
> for a bevelled box.

If all you want to do is make a bevelled box, use the BevelBox()
macro from my Throughly Useful Macros file.

  http://users4.50megs.com/enphilistor/macs.htm

The macro intersects three boxes to produce the beveled box;
the code is much neater.

> // Scalar Triple Product of 3 vectors
> #macro S3Prod(v1, v2, v3)
> 
>   vdot(v1, vcross(v2, v3))
> 
> #end // macro S3Prod

This acutally produces the determinant of the matrix formed by the
three vectors.

Regards,
John
-- 
ICQ: 46085459


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Source code for bevelled box
Date: 11 Oct 2000 12:17:30
Message: <39E49199.E9485C80@online.no>
John VanSickle wrote:

> Tor Olav Kristensen wrote:
> >
> > Here's my "Total Overkill" code for calculating position of corners
> > for a bevelled box.
>
> If all you want to do is make a bevelled box, use the BevelBox()
> macro from my Throughly Useful Macros file.

Yes, my solution is much too complex to be useful for making a
bevelled box.

But since he asked about the coordinates for the corners,
and since I was working on some macros that dealt with such
problems, I just tried to put them together in a way that solved
his problem


>   http://users4.50megs.com/enphilistor/macs.htm
>
> The macro intersects three boxes to produce the beveled box;
> the code is much neater.

I agree that this is a much more efficient way to make a bevelled box.


> > // Scalar Triple Product of 3 vectors
> > #macro S3Prod(v1, v2, v3)
> >
> >   vdot(v1, vcross(v2, v3))
> >
> > #end // macro S3Prod
>
> This acutally produces the determinant of the matrix formed by the
> three vectors.

Yes, I know.


Regards

Tor Olav


Post a reply to this message

From: John VanSickle
Subject: Re: Source code for bevelled box
Date: 11 Oct 2000 20:44:20
Message: <39E50A81.BA7FCC50@erols.com>
Tor Olav Kristensen wrote:
> 
> John VanSickle wrote:
> 
> > Tor Olav Kristensen wrote:
> > >
> > > // Scalar Triple Product of 3 vectors
> > > #macro S3Prod(v1, v2, v3)
> > >
> > >   vdot(v1, vcross(v2, v3))
> > >
> > > #end // macro S3Prod
> >
> > This acutally produces the determinant of the matrix formed by the
> > three vectors.
> 
> Yes, I know.

Okay, it's just that I'd never seen it called the "scalar triple
product."

Regards,
John
-- 
ICQ: 46085459


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Source code for bevelled box
Date: 11 Oct 2000 21:14:40
Message: <39E50F85.26415E5@online.no>
John VanSickle wrote:

> Tor Olav Kristensen wrote:
> >
> > Here's my "Total Overkill" code for calculating position of corners
> > for a bevelled box.
>
> If all you want to do is make a bevelled box, use the BevelBox()
> macro from my Throughly Useful Macros file.

I have had a little look at your BevelBox macro.
It's a nice way to make a I bevelled box.

But I have a optimalization to suggest for you.
I belive that if you rewrite it like this:

#macro BevelBox(Start,End,Bevel)
  #local pS=Start+<0,0,0>;
  #local pE=End+<0,0,0>;
  #local sB=Bevel/sqrt(8);
  #local vC=(pS+pE)/2;
  #local vD=<abs(pS.x-pE.x),abs(pS.y-pE.y),abs(pS.z-pE.z)>/2;
  #local xE=(vD.y+vD.z)/2-sB;
  #local yE=(vD.x+vD.z)/2-sB;
  #local zE=(vD.x+vD.y)/2-sB;

  intersection {
    box { -1,1 matrix <vD.x,0,0, 0,xE,xE, 0,-xE,xE, vC.x,vC.y,vC.z> }
    box { -1,1 matrix <yE,0,-yE, 0,vD.y,0, yE,0,yE, vC.x,vC.y,vC.z> }
    box { -1,1 matrix <zE,zE,0, -zE,zE,0, 0,0,vD.z, vC.x,vC.y,vC.z> }
    bounded_by { box { pS,pE } }
  }
#end

then it will have 2 less divisions and 1 less addition and 1 less
subtraction.


This is how I would have done it (if I were to use your method):


#macro BevelledBox(pCorner1, pCorner2, sBevel)

  #local vB=(pCorner2-pCorner1+<0,0,0>)/2;
  #local vD=<abs(vB.x),abs(vB.y),abs(vB.z)>;
  #local vE=(<vD.y+vD.z,vD.x+vD.z,vD.x+vD.y>-sBevel/sqrt(2)*<1,1,1>)/2;

  intersection {
    box { -1,1 matrix <vD.x,0,0,0,vE.x,vE.x,0,-vE.x,vE.x,0,0,0> }
    box { -1,1 matrix <vE.y,0,-vE.y,0,vD.y,0,vE.y,0,vE.y,0,0,0> }
    box { -1,1 matrix <vE.z,vE.z,0,-vE.z,vE.z,0,0,0,vD.z,0,0,0> }
    bounded_by { box { -vD,vD } }
    translate pCorner1+vB
  }

#end // macro BevelledBox


I haven't done much testing, but it seems to do the same.


Regards,

Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Source code for bevelled box
Date: 11 Oct 2000 21:19:17
Message: <39E51098.DA713AC0@online.no>
John VanSickle wrote:

> Tor Olav Kristensen wrote:
> >
> > John VanSickle wrote:
> >
> > > Tor Olav Kristensen wrote:
> > > >
> > > > // Scalar Triple Product of 3 vectors
> > > > #macro S3Prod(v1, v2, v3)
> > > >
> > > >   vdot(v1, vcross(v2, v3))
> > > >
> > > > #end // macro S3Prod
> > >
> > > This acutally produces the determinant of the matrix formed by the
> > > three vectors.
> >
> > Yes, I know.
>
> Okay, it's just that I'd never seen it called the "scalar triple
> product."

http://mathworld.wolfram.com/ScalarTripleProduct.html
http://www.torget.se/users/m/mauritz/math/vect/determ.htm

:)

Regards,

Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html


Post a reply to this message

From: John VanSickle
Subject: Re: Source code for bevelled box
Date: 12 Oct 2000 09:26:58
Message: <39E5BC20.1D8ED209@erols.com>
Tor Olav Kristensen wrote:
> 
> But I have a optimalization to suggest for you.
> I belive that if you rewrite it like this:
> then it will have 2 less divisions and 1 less addition and 1 less
> subtraction.

Hmm.  I never worry too much about parsing speed.  My current IRTC
entry, for instance, has a shot that takes 3 minutes to parse for each
frame, which is the longest that any non-experimental scene of mine
has taken to parse.  Usually my parsing is done in ten to fifteen
seconds.

Regards,
John


Post a reply to this message

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