Leaning tower

Global parameters

DEF scalefactor = 3.16655256;
DEF InternalBasementRadius = scalefactor*0.7;
DEF ExternalBasementRadius = scalefactor*3.2;
DEF BasementHeight = scalefactor*1.3;
DEF WidthBasement = ExternalFirstFloorRadius - InternalFirstFloorRadius;
DEF InternalFirstFloorRadius = scalefactor*1.2;
DEF ExternalFirstFloorRadius = scalefactor*2.5;
DEF InternalWallRadius = scalefactor*1.25;
DEF ExternalWallRadius = scalefactor*2.1;
DEF FirstFloorHeight = 3.15 * scalefactor;
DEF WallHeight = 9.35 * scalefactor;
DEF FirstRingPerimeter = 5.15 * scalefactor * PI;
DEF FirstRingColumnArcWidth = FirstRingPerimeter/12;
DEF ColumnScaling = (WallHeight/6)/(size:3:(Column_1:(pi/24)));

Tower basement

DEF basament1 = (Cylinder:<ExternalBasementRadius,BasementHeight/2>:24) -
        (Cylinder:<InternalBasementRadius,BasementHeight/2>:24);
DEF basament2 = thebasament - cone2
WHERE
        thebasament = basament1 & cone1,
        cone1 = cone:<ExternalBasementRadius,hcone>:24,
        hcone = tg_alpha * ExternalBasementRadius,
        tg_alpha = (ExternalBasementRadius -
                ExternalFirstFloorRadius)/(BasementHeight/2),
        reversed_cone = S:3:-1:cone1,
        cone2 = T:3:tcone:reversed_cone,
        tcone = tg_alpha * (ExternalBasementRadius - InternalBasementRadius)
END;
DEF Basament = STRUCT:< basament1, T:3:(BasementHeight/2):basament2 >;

Tower kernel

DEF FirstFloor =
Cylinder:<ExternalFirstFloorRadius,FirstFloorHeight>:24 -
        Cylinder:<InternalFirstFloorRadius,FirstFloorHeight>:24;
DEF Kernel = Cylinder:<ExternalWallRadius,WallHeight>:24 -
        Cylinder:<InternalWallRadius,WallHeight>:24;

Tower terrace

DEF Terrace = (T:3:(0.095*scalefactor/2) ~ STRUCT):< S:3:-1:wafer1,
wafer1>
WHERE
        wafer1 = terrace1 & cone1,
        terrace1 = Cylinder:<1.1*ExternalFirstFloorRadius,
                0.095*scalefactor/2>:24 -
        Cylinder:<ExternalWallRadius, 0.095*scalefactor/2>:24,
        hcone = tg_alpha * 1.1*ExternalFirstFloorRadius,
        tg_alpha = (0.05*ExternalFirstFloorRadius)/(0.095*scalefactor),
        cone1 = cone:<1.1*ExternalFirstFloorRadius, hcone>:24
END;

First tower ring

DEF Column_1 (angle::isreal) = (optimize~R:<1,2>:(angle)
        ~T:<1,2,3>:<2.6*scalefactor,0,-0.2*scalefactor>):
        (box TOP basis TOP fusto TOP basis TOP capitello TOP box1)
WHERE
        unit = FirstRingColumnArcWidth/2,
        basis = Cylinder:<0.11*scalefactor,0.03*scalefactor>:18,
        fusto = Cylinder:<0.095*scalefactor,1.75*scalefactor>:18,
        capitello = truncone:<0.09*scalefactor,0.14*scalefactor,0.18*scalefactor>:18,
        box = (T:<1,2>:<-0.15*scalefactor,-0.15*scalefactor>~cuboid):
                <0.30*scalefactor,0.30*scalefactor,0.28*scalefactor>,
        box1 = cuboid:<0.30*scalefactor,0.30*scalefactor,0.05*scalefactor>
END;

Other tower rings

DEF Column_2 (angle::isreal) = (optimize~R:<1,2>:(angle)
        ~T:<1,2,3>:<2.53*scalefactor,0,0.09*scalefactor>):
        (S:3:columnscaling:( box0 TOP basis0 TOP basis1 TOP basis2 TOP fusto
                TOP basis2 TOP capitello)
                        align:<<1,max,max>,<2,med,med>,<3,max,min>>
        box1)
WHERE
        unit = FirstRingColumnArcWidth/2,
        transl = T:<1,2>:<-0.12*scalefactor,-0.12*scalefactor>,
        box0 = (transl~cuboid):
                <0.24*scalefactor,0.24*scalefactor,0.06*scalefactor>,
        basis0 = Cylinder:<0.11*scalefactor,0.02*scalefactor>:18,
        basis1 = Cylinder:<0.08*scalefactor,0.04*scalefactor>:18,
        basis2 = Cylinder:<0.09*scalefactor,0.02*scalefactor>:18,
        fusto = Cylinder:<0.07*scalefactor,1.40*scalefactor>:18,
        capitello = truncone:<0.07*scalefactor,0.10*scalefactor,0.16*scalefactor>:18,
        box1 = MKPOL:<<<0,y,0>,<0,-:y,0>,<x,y - dy,0>,<x,dy - y,0>,
        <0,y,z>,<0,-:y,z>,<x,y - dy,z>,<x,dy - y,z>>,<1..8>,<(1)>>
        WHERE
                y = 0.13*scalefactor, x = -4*y, z = y, dy = tan:(pi/36)*(-:x)
        END
END;

Arcs of first ring

DEF Arch (r1,r2,w::IsRealPos) =
        (optimize~R:<1,3>:(pi/-2)~T:3:(w/-2)~STRUCT):<
        (Cylinder:<r2,w>:24 - (Cylinder:<r1,w>:24 +
                (T:2:(-:r2)~CUBOID):<r2,2*r2,w>)) ,
        (T:2:(-:r2)):(CUBOID:<r2*sin:(pi/12),2*r2,w>) -
                (T:2:(-:r1)):(CUBOID:<r2*sin:(pi/12),2*r1,w>)
> ;
DEF Arc_1_1 = T:<1,2,3>:<2.45*scalefactor,0,2.30*scalefactor>:
        ((Arch:< 0.8*unit, unit, unit/2 >) STRUCT (Arch:< unit, 1.05*unit,
                unit/1.5 >))
WHERE
        unit = FirstRingColumnArcWidth/2
END;
DEF Wall_1 = T:3:(2.30*scalefactor):
        (TheCylinder - Ottusangle - Hole:<1.05*unit, unit/1.5> )
WHERE
        unit = FirstRingColumnArcWidth/2,
        TheCylinder = Cylinder:<1.08*ExternalFirstFloorRadius, 1.1*unit>:24 -
        Cylinder:<ExternalWallRadius, 1.1*unit>:24,
        Ottusangle = ((optimize~R:<1,2>:(pi/12)~T:1:(-100)~CUBOID):<200,100,100> +
        (optimize~R:<1,2>:(11*pi/12)~T:1:(-100)~CUBOID):<200,100,100> ),
        Hole (r2,w::isrealpos) = (T:<1,2>:<2.45*scalefactor,0>):(
                (R:<1,3>:(pi/-2)~S:3:2~T:3:(w/-2)):(Cylinder:<r2,2*w>:24 -
                        (T:2:(-:r2)~CUBOID):<r2,2*r2,w>) )
END;
DEF FirstColumnRing = (STRUCT ~ ##:12):< Column_1:(pi/12), Arc_1_1,
        Wall_1, R:<1,2>:(pi/6) >;

Arcs of other rings

DEF Arc_2_1(angle::isreal) = (optimize~R:<1,2>:(angle)~T:<1,2,3>:
                <2.40*scalefactor,0,2.10*scalefactor*columnscaling>):
                        ((Arch:< 0.65*unit, 0.9*unit, 1.5*unit >) STRUCT (Arch:< 0.9*unit,
                        unit, unit/0.75 >))
WHERE
        unit = FirstRingColumnArcWidth/4
END;
DEF Wall_2 (angle::isreal) =
        (optimize~R:<1,2>:(angle)~T:3:(2.10*scalefactor*columnscaling)):
                (TheCylinder - Ottusangle - Hole:<unit, unit/0.75> )
WHERE
        unit = FirstRingColumnArcWidth/4,
        TheCylinder = Cylinder:<1.05*ExternalFirstFloorRadius, 1.35*unit>:48 -
        Cylinder:<ExternalWallRadius, 1.35*unit>:24,
        Ottusangle = ((optimize~R:<1,2>:(pi/24)~T:1:(-100)~CUBOID):<200,100,100> +
                (optimize~R:<1,2>:(23*pi/24)~T:1:(-100)~CUBOID):<200,100,100> ),
        Hole (r2,w::isrealpos) = (T:<1,2>:<2.45*scalefactor,0>):(
                (R:<1,3>:(pi/-2)~S:3:2~T:3:(w/-2)):(Cylinder:<r2,2*w>:24 -
                        (T:2:(-:r2)~CUBOID):<r2,2*r2,w>) )
END;
DEF SecondColumnRing = (STRUCT ~ ##:24):< Column_2:(pi/12),
                Arc_2_1:(pi/24), Wall_2:(pi/24), R:<1,2>:(pi/12) >;

Internal steps

DEF radiusSteps = 1.9 * scalefactor;
DEF pitchSteps = (7/1.5) * scalefactor;
DEF angleSteps = 21*pi/4 ;
DEF numberOfSteps = 293;
DEF alphaStep = -:angleSteps/numberOfSteps;
DEF zetaStep = (FirstFloorHeight+WallHeight)/numberOfSteps;
DEF stepVolume = (T:1:(-:radiusSteps)~CUBOID):(<0.4,0.11,0.8>
                scalarvectprod scalefactor);
DEF stepsSegment = (optimize~STRUCT~CAT~TRANS):
        < translations, rotations, objects >
WHERE
        translations = #:17:(T:3:zetaStep),
        rotations = #:17:(R:<1,2>:alphaStep),
        objects = #:17:stepVolume
END;
DEF steps = (optimize~STRUCT~##:17):< stepsSegment,
                R:<1,2>:(17*alphaStep), T:3:(17*ZetaStep) >;
DEF fabric = STRUCT:<
        T:3:(-:BasementHeight):Basament, Steps color Red,
        FirstFloor, T:3:FirstFloorHeight:Kernel,
        FirstColumnRing,
        T:3:(FirstFloorHeight - 0.095*scalefactor),
        Terrace, (STRUCT ~ ##:5):< SecondColumnRing, T:3:(WallHeight/5),
                Terrace >,
>;

Tower cap

DEF lastFloorHeight = WallHeight/5;
DEF TowerCap = lastWall STRUCT
        ((T:3:lastFloorHeight~JOIN~truncone:< ExternalFirstFloorRadius,
                ExternalWallRadius, 0.4*scalefactor >):24
                - Join:(MySphere:externalWallRadius:<12,24>))
WHERE
        lastWall = Cylinder:<ExternalWallRadius,lastFloorHeight>:24 -
                Cylinder:<InternalWallRadius,lastFloorHeight>:24
END;
DEF MySphere (radius::IsRealPos)(n,m::IsIntPos)
        = MAP:[fx,fy,fz]:domain
WHERE
        fx = K:radius * - ~ SIN ~ S2 * COS ~ S1,
        fy = K:radius * COS ~ S1 * COS ~ S2,
        fz = K:radius * SIN ~ S1,
        domain = (Intervals:PI:n * Intervals:(2*PI):m)
END;
DEF fabric = STRUCT:<
        T:3:(-:BasementHeight):Basament, Steps color Red,
        FirstFloor, T:3:FirstFloorHeight:Kernel,
        FirstColumnRing,
        T:3:(FirstFloorHeight - 0.095*scalefactor),
        Terrace, (STRUCT ~ ##:6):< SecondColumnRing, T:3:(WallHeight/5),
                Terrace >,
        T:3:(WallHeight),
        TowerCap
>;

Tower cap (seventh order)

DEF Int7Height = scalefactor*1.7;
DEF Ext7Height = scalefactor*2.3;
DEF c11 = bezier:s1:<<InternalWallRadius,0,0>,<InternalWallRadius,0,Int7Height>>;
DEF c12 = bezier:s1:<<ExternalWallRadius,0,0>,<ExternalWallRadius,0,Ext7Height>>;
DEF surf1 = bezier:s2:<c11,c12>;
DEF c21 = hermite:<<InternalWallRadius,0,Int7Height>,<0.75,0,Ext7Height - 0.25>,<-1,0,2.5>,<-3,0,0>>;
DEF c22 = bezier:s1:<<ExternalWallRadius,0,Ext7Height>,<0.75,0,Ext7Height>>;
DEF surf2 = bezier:s2:<c21,c22>;
DEF c31 = bezier:s1: <<ExternalWallRadius,0,Int7Height>,<ExternalWallRadius,0,Ext7Height>>;
DEF c32 = bezier:s1: <<ExternalWallRadius+1,0,Int7Height>,
        <ExternalWallRadius+1,0,(Int7Height +Ext7Height)/2>>;
DEF surf3 = bezier:s2:<c31,c32>;
DEF solid (surf::isvect) = <
        (s1:surf * cos~s3) - (s2:surf * sin~s3),
        (s2:surf * cos~s3) + (s1:surf * sin~s3),
        s3:surf >;
DEF out1 = MAP:(solid:surf1):(intervals:1:1 * intervals:1:1 * intervals:(3*pi/2):18);
DEF out2 = MAP:(solid:surf2):(intervals:1:9 * intervals:1:1 * intervals:(3*pi/2):18);
DEF out3 = MAP:(solid:surf3):((sqr~intervals:1):1 * intervals:(3*pi/2):18);
DEF cap = STRUCT:<out1,out2,out3>;

Tower bell

DEF Column_b = (optimize
        ~T:<1,2,3>:< (-18/24)*2.53*scalefactor,0,0.09*scalefactor>):
        (S:3:columnscaling:( box0 TOP basis0 TOP basis1 TOP basis2 TOP fusto
                TOP basis2 TOP capitello)
                        align:<<1,max,max>,<2,med,med>,<3,max,min>>
        box1)
WHERE
        unit = FirstRingColumnArcWidth/2,
        transl = T:<1,2>:<-0.12*scalefactor,-0.12*scalefactor>,
        box0 = (transl~cuboid):<0.24*scalefactor,0.24*scalefactor,0.06*scalefactor>,
        basis0 = Cylinder:<0.11*scalefactor,0.02*scalefactor>:18,
        basis1 = Cylinder:<0.08*scalefactor,0.04*scalefactor>:18,
        basis2 = Cylinder:<0.09*scalefactor,0.02*scalefactor>:18,
        fusto = Cylinder:<0.07*scalefactor,1.40*scalefactor>:18,
        capitello = truncone:<0.07*scalefactor,0.10*scalefactor,0.16*scalefactor>:18,
        box1 = box0
END;
DEF Arc_2_b = (optimize~R:<1,2>:(pi/18)~T:<1,2,3>:
                <(18/ 24)*2.53*scalefactor,0,2.08*scalefactor*columnscaling>):
                        (Arch:< 0.65*unit, 0.9*unit, 0.5*unit > STRUCT Arch:< 0.9*unit,
                        1.1*unit, 0.65*unit > )
WHERE
        unit = FirstRingColumnArcWidth/4
END;
DEF Wall_b (angle::isreal) = (optimize~R:<1,2>:(angle)
        ~ T:3:((18/ 24)*2.10*scalefactor*columnscaling)):
                (TheCylinder - Ottusangle - Hole:<unit, unit/0.75> )
WHERE
        unit = FirstRingColumnArcWidth/4,
        TheCylinder = Cylinder:<1.05*ExternalFirstFloorRadius, 1.35*unit>:48 -
        Cylinder:<ExternalWallRadius, 1.35*unit>:24,
        Ottusangle = ((optimize~R:<1,2>:(pi/24)~T:1:(-100)~CUBOID):<200,100,100> +
        (optimize~R:<1,2>:(23*pi/24)~T:1:(-100)~CUBOID):<200,100,100> ),
        Hole (r2,w::isrealpos) = (T:<1,2>:<2.45*scalefactor,0>):(
        (R:<1,3>:(pi/-2)~S:3:2~T:3:(w/-2)):(Cylinder:<r2,2*w>:24 -
                (T:2:(-:r2)~CUBOID):<r2,2*r2,w>) )
END;
DEF TopTower = STRUCT:< SecondColumnRing, cap, T:3:(WallHeight/5), Terrace>;

Belt Tower

DEF tooth = (optimize~STRUCT):< lungo, R:<1,2>:(pi/106), corto >
where
        raggio = ExternalWallRadius,
        lungo = mymap1:<0,0.1> TOP mymap2:<0.1,0.1>,
        corto = mymap2:< -0.05,0.2>,
        mymap1 (dr,h::isreal) = MAP:<(s2+s3)*cos~s1,(s2+s3)*sin~s1,s3>:
        (intervals:(pi/106):1 * T:1:(InternalWallRadius):(intervals:(width:dr):1)
                * intervals:h:1),
        mymap2 (dr,h::isreal) = MAP:<(s2)*cos~s1,(s2)*sin~s1,s3>:(intervals:(pi/106):1
                * T:1:(InternalWallRadius):(intervals:(width:dr):1) * intervals:h:1),
        width(dr::isreal) = ExternalWallRadius - InternalWallRadius + dr
end;
DEF plateau = (optimize~STRUCT~##:106):<tooth,R:<1,2>:(2*pi/106)>;
DEF BeltColumnRing = (STRUCT ~ ##:6):
        < Column_b, Arc_2_b, R:<1,2>:(pi/9),Column_b, Arc_2_b,
        R:<1,2>:(pi/9), Arc_2_b, R:<1,2>:(pi/9) >
        STRUCT T:3:5.75:plateau;
DEF BeltWalls = MyRing:(3*pi/9):
        <InternalWallRadius,ExternalWallRadius*6/7>:<6,1> * Q:5.75;
DEF SmallWindow1 = MyRing:((3*pi)/(18*4)):
        <InternalWallRadius - 1,ExternalWallRadius*6/7 + 1>:<2,1> * Q:1.75;
DEF SmallWindow2 = MyRing:((4*pi)/(18*5) + pi/64):
        <InternalWallRadius - 1,ExternalWallRadius*6/7 + 1>:<2,1> * Q:<-1.75,-0.35,2>;
DEF MyRing (angle::IsReal)(r1,r2::IsRealPos)(n,m::IsIntPos) =
        MAP:[s2 * cos ~ S1, s2 * sin ~ S1]:domain
WHERE
        domain = T:2:r1:(Intervals:angle:n * Intervals:(r2 - r1):m)
END;
DEF hole3 (angle::IsReal)(r1,r2::IsRealPos) = MAP:
        (Bezier:S3:([portal1:(angle), portal2:(angle)]:<r1,r2>)):
        (intervals:1:1 * intervals:1:12 * intervals:1:1)
WHERE
        portal1(angle::IsReal)(r1,r2::IsRealPos) =
                CubicHermite:S2:< c1,c2,t1,t2 >,
        portal2(angle::IsReal)(r1,r2::IsRealPos) =
                Bezier:S2:< c1,c2 > vectsum <K:0,K:0,K:-0.1>,
        c1 = Bezier:S1:line1,
        line1 = <<r1,0,0>,<r2,0,0>>,
        c2 = Bezier:S1:line2,
        line2 = AA:(UK ~ R:<1,2>:angle ~ MK):line1,
        t1 = Bezier:S1:<<0,0,2>,<0,0,4>>,
        t2 = Bezier:S1:<<0,0,-2>,<0,0,-4>>
END;
DEF Window3 = MyRing:(2*pi/9 - 0.2):
        <InternalWallRadius - 1,ExternalWallRadius*6/7 + 1>:<1,1> * Q:2.5;
DEF Hole3 = (T:3:(2.5)~R:<1,2>:(0.15/2)):(hole3:(pi/9):
        <InternalWallRadius - 1,ExternalWallRadius*6/7 + 1 >);
DEF BeltTower = (STRUCT~##:6):<SectorWall,R:<1,2>:(pi/3)> STRUCT
        BeltColumnRing;
DEF SectorWall = -:<
        BeltWalls,
        R:<1,2>:((3*pi)/(18*5)):SmallWindow1,
        R:<1,2>:(pi/36):SmallWindow2,
        R:<1,2>:(pi/9 + 0.1):Window3 > % STRUCT
        (R:<1,2>:(pi/9 + 0.1):Hole3 color red) % ;

Final tower assembly

DEF fabric = STRUCT:< T:3:(-:BasementHeight):Basament, Steps color Red,
FirstFloor, T:3:FirstFloorHeight:Kernel,
        FirstColumnRing,
        T:3:(FirstFloorHeight - 0.095*scalefactor),
        Terrace,
        (STRUCT ~ ##:5):< SecondColumnRing, T:3:(WallHeight/5), Terrace >,
        T:3:WallHeight, TowerCap, TopTower,
        T:3:(max:3:TowerCap - 0.3), BeltTower
>;
view:fabric;
% export:(fabric):~/plasm/wrl/pisa.wrl; %

 

PLaSM is Free Software and may be distributed under GNU LGPL