POV-Ray : Newsgroups : povray.binaries.images : Archway macro : Re: Archway macro Server Time
5 Nov 2024 14:23:48 EST (-0500)
  Re: Archway macro  
From: Bill Pragnell
Date: 17 Aug 2006 05:50:00
Message: <web.44e43abb4f0e252c731f01d10@news.povray.org>
Right, here's the macro.

There has to be an even number of bricks in the arch, even without a
keystone. If the edge radius is zero, the macro leaves out all the edge
curved shapes to save memory, etc. Enjoy!

// curved-brick macro. creates bricks curved in x-z plane.
// rin = inner radius
// rout = outer radius
// redge = edge radius
// depf = thickness of brick perpendicular to curvature plane
// angl = angular size of brick
#macro ArcBrick(rin, rout, redge, depf, angl)
  #local h = depf/2;
  #local hin = depf/2-redge;
  #local xout = rout*sin(radians(angl/2));
  #local yin = rin*cos(radians(angl/2));
  intersection {
    union {
      difference {
        cylinder { <0, h, 0>, <0, -h, 0>, rout-redge }
        cylinder { <0, depf, 0>, <0, -depf, 0>, rin+redge } }
      difference {
        cylinder { <0, hin, 0>, <0, -hin, 0>, rout }
        cylinder { <0, depf, 0>, <0, -depf, 0>, rin } }
      #if (redge > 0)
        torus { rin+redge, redge translate <0, hin, 0> }
        torus { rin+redge, redge translate <0, -hin, 0> }
        torus { rout-redge, redge translate <0, hin, 0> }
        torus { rout-redge, redge translate <0, -hin, 0> }
      #end }
    plane { <-1, 0, 0>, -redge rotate <0, -angl/2, 0> }
    plane { <1, 0, 0>, -redge rotate <0, angl/2, 0> }
    #if (angl < 180)
      bounded_by { box { <-xout, -depf, yin>, <xout, depf, rout> } }
    #end }
  intersection {
    difference {
      cylinder { <0, hin, 0>, <0, -hin, 0>, rout-redge }
      cylinder { <0, depf, 0>, <0, -depf, 0>, rin+redge } }
    plane { <-1, 0, 0>, 0 rotate <0, -angl/2, 0> }
    plane { <1, 0, 0>, 0 rotate <0, angl/2, 0> }
    #if (angl < 180)
      bounded_by { box { <-xout, -depf, yin>, <xout, depf, rout> } }
    #end }
  #if (redge > 0)
    // corners
    sphere { <-redge, hin, rin+redge>, redge rotate <0, angl/2, 0> }
    sphere { <-redge, -hin, rin+redge>, redge rotate <0, angl/2, 0> }
    sphere { <-redge, hin, rout-redge>, redge rotate <0, angl/2, 0> }
    sphere { <-redge, -hin, rout-redge>, redge rotate <0, angl/2, 0> }
    sphere { <redge, hin, rin+redge>, redge rotate <0, -angl/2, 0> }
    sphere { <redge, -hin, rin+redge>, redge rotate <0, -angl/2, 0> }
    sphere { <redge, hin, rout-redge>, redge rotate <0, -angl/2, 0> }
    sphere { <redge, -hin, rout-redge>, redge rotate <0, -angl/2, 0> }
    // vertical edges
    cylinder { <-redge, -hin, rin+redge>, <-redge, hin, rin+redge>, redge
               rotate <0, angl/2, 0> }
    cylinder { <redge, -hin, rin+redge>, <redge, hin, rin+redge>, redge
               rotate <0, -angl/2, 0> }
    cylinder { <-redge, -hin, rout-redge>, <-redge, hin, rout-redge>, redge
               rotate <0, angl/2, 0> }
    cylinder { <redge, -hin, rout-redge>, <redge, hin, rout-redge>, redge
               rotate <0, -angl/2, 0> }
    // in-plane edges
    cylinder { <-redge, hin, rin+redge>, <-redge, hin, rout-redge>, redge
               rotate <0, angl/2, 0> }
    cylinder { <-redge, -hin, rin+redge>, <-redge, -hin, rout-redge>, redge
               rotate <0, angl/2, 0> }
    cylinder { <redge, hin, rin+redge>, <redge, hin, rout-redge>, redge
               rotate <0, -angl/2, 0> }
    cylinder { <redge, -hin, rin+redge>, <redge, -hin, rout-redge>, redge
               rotate <0, -angl/2, 0> }
  #end
#end

// archway macro. creates arches in x-y plane.
// Total_Angle = total angular size of arch
// Keystone_Angle = angular size of keystone
// nBricks = number of non-keystone bricks in arch (must be even)
// Padding = spacing between bricks as a fraction of total brick size
// rInner = inner radius
// rOuter = outer radius
// kInner = keystone inner radius
// kOuter = keystone outer radius
// Thickness = thickness of arch
// rEdge = edge radius
#macro Arch(Total_Angle, Keystone_Angle, nBricks, Padding, rInner, rOuter,
kInner, kOuter, Thickness, rEdge)
  #local Brick_Angle = (Total_Angle - Keystone_Angle)/nBricks;
  #local ang = -(Total_Angle/2 - Brick_Angle/2);
  #local n = 1;
  #while (n <= nBricks/2)
    union {
      ArcBrick(rInner, rOuter, rEdge, Thickness, (1-Padding/2)*Brick_Angle)
      rotate <-90, 0, 0> rotate <0, 0, ang> }
    #local n = n + 1;
    #local ang = ang + Brick_Angle;
  #end
  #if (Keystone_Angle > 0)
    union {
      ArcBrick(kInner, kOuter, rEdge, Thickness,
               Keystone_Angle-Brick_Angle*Padding/2)
      rotate <-90, 0, 0> }
  #end
  #local ang = Keystone_Angle/2 + Brick_Angle/2;
  #while (n <= nBricks)
    union {
      ArcBrick(rInner, rOuter, rEdge, Thickness, (1-Padding/2)*Brick_Angle)
      rotate <-90, 0, 0> rotate <0, 0, ang> }
    #local n = n + 1;
    #local ang = ang + Brick_Angle;
  #end
#end

// example arch:
union {
  Arch(240, 20, 24, 0.05, 0.75, 0.9, 0.7, 0.9, 0.3, 0.025)
  texture { Stone } }


Bill


Post a reply to this message

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