POV-Ray : Newsgroups : povray.text.scene-files : Source code for bevelled box : Source code for bevelled box Server Time
6 Oct 2024 08:41:36 EDT (-0400)
  Source code for bevelled box  
From: Tor Olav Kristensen
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

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