|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
|
|