/* POV-RAY PROGRAM ~/Private/website/landshare/shell/shell.pov TO GENERATE THE ELLIPSOIDAL PANEL VERSION OF THE MODULES AND CONNECTING PASSAGES OF THE ACCOMMODATION UNIT OF THE EXPERIMENTAL FARMLET OF THE LANDSHARE PROJECT by Robert John Morton YE572246C Terminal command for: Small Frame: povray shell.pov +W320 +H240 Medium Frame: povray shell.pov +W640 +H480 Large Frame: povray shell.pov +W1280 +H960 In a Nautilus window do "Ctrl-L Ctrl-Insert" to grab the directory path to this file. Then open a terminal and enter "cd Shift-Insert Enter" to take the terminal to this file's working directory. Finally, cut and paste one of the above commands into the terminal and press "Enter" to start tyhe rendering process. */ #include "colors.inc" #include "shapes.inc" #include "textures.inc" #include "metals.inc" #include "stones.inc" #include "glass.inc" global_settings{max_trace_level 256} /*max possible is 256 For a normal view, use oh = 100. For an exploded view at less than rd = 45 degrees, use oh = 120. For rd > 45, use oh = 150. Standard views are at rd = 10, 20, 30, 45, 60, 90 However, don't use rd = 90 because the azimuthal orientation goes potty. Use rd = 89.9 */ #declare oh = 400; //hypotenuse distance to observer: 100 normal 120 exploded #declare rd = 1; /*angle of elevation to observer: 0 for internal view x-offset (East-West) 0 = due South | height of observer above ground | | horizontal distance of observer from object | | | object is at the coordinate zero | | | | 13 for external 60 for internal views | | | | | */ camera{location<0, oh*sind(rd), oh*cosd(rd)> look_at<0,0,0> angle 13} /* LIGHTING --------------------------------------------------------------------------------------- light_source { <15, 200, 30> color rgb <1, 1, 1> } // for quick tests light_source { <7.25, 1.1, 8> color rgb <1, 1, 1> } // for quick tests 1) Simulate the sun */ #declare sun_white = light_source { // WHITE SUN IS ON THE HORIZON DUE SOUTH <0, 0, 1000> // located at south horizon color rgb <1,1,1> // white light cylinder // confined to a cylindrical beam radius 600 // of radius 100 units diameter at full intensity falloff 2000 // falling off to zero brightness at 70 units diameter area_light <1,0,0>, <0,0,1>, 20,20 // lighting element is a 20 x 20 array of pixels adaptive 1 // the normal of which is determined by the vectors jitter // adaptive = minimise number of test rays required point_at <0, 0, 0> // the light beam is aimed at the co-ordinate origin } // jitter softens shadows #declare sun_yellow = light_source { //YELLOW SUN IS ON THE HORIZON DUE SOUTH <0, 0, 1000> // located at south horizon color rgb <1,1,1> // yellow light cylinder // confined to a cylindrical beam radius 300 // of radius 100 units diameter at full intensity falloff 500 // falling off to zero brightness at 70 units diameter area_light <1,0,0>, <0,0,1>, 20,20 // lighting element is a 20 x 20 array of pixels adaptive 1 // the normal of which is determined by the vectors jitter // adaptive = minimise number of test rays required point_at <0, 0, 0> // the light beam is aimed at the co-ordinate origin } // jitter softens shadows /* rotate the sun to its desired elevation eg -60 means the sun is 60 degrees above the horizon due south. Rotate it round the z-axis to simulate time of day eg -15 means 15 degrees (one hour) before noon. Sun: ascention 80 degrees, declination 30 degrees */ object{sun_white rotate<-80,0,-30>} //object { sun_yellow } // 2) simulate light from the horizon #declare luz = light_source{<0, -1.6, 500> color rgb <.15, .25, .3>} //horizon light #declare horizonglow = union{ #declare iii = 0; #while(iii < 360) object { luz rotate <0,iii,0> } #declare iii=iii + 51.428571429; #end } // object{horizonglow rotate <0,0,0>} //rotate the 7 horizon lights to best position // BACKGROUND ------------------------------------------------------------------------------------- #declare ground_level = -4; //amount ground is below co-ordinate origin (in metres) #declare rp = 6378140; //Earth radius (metres) sphere{<0,0,0>, rp //create spherical planet the size of the Earth texture{ //define its ground texture that comprises: pigment{color rgb <0.27, 0.34, 0.18>} // 0.56640625/1.15625= // pigment{color rgb <1,1,1>} finish{diffuse 0.2 ambient 0.9} } translate<0, ground_level - rp, 0> } //translate it downwards to ground level sky_sphere{ //standard sky sphere pigment{ gradient y color_map{ [(1 - cos(radians( 30)))/2 color White] [(1 - cos(radians(120)))/2 color rgb<0.4,0.6,1>] } scale 2 translate -1 } } /* SPECIAL TEXTURES USED IN THIS PROJECT: The upper declaration for each colour is the conservative colouring used for the finished module. The lower declaration is for a bold exaggerated version of the colour for the purpose of illustrsating clearly the individual panels. */ #declare dm = texture{pigment{color rgb<0.50, 0.52, 0.49> //grey with a suggestion of light green // rgb<0, 0.6, 1> //alternative metiallic blue } finish{phong 0.8 ambient 0.5} } #declare lm = texture{pigment{color rgb<0.60, 0.55, 0.53> //grey with a hint of red // rgb<0.9, 0.9, 0.8> //alternative metallic white } finish{phong 0.8 ambient 0.5} } #declare GLASS = texture{pigment{color Col_Glass_General} finish{F_Glass8}} #declare greene = texture{ //define its ground texture that comprises: pigment{color rgb<0.629, 0.664, 0.258>} // pigment{color rgb<0.36, 0.38, 0.33>} finish{ambient 0.2 phong 0.5} } // GLEBA CIRCLE ----------------------------------------------------------------------------------- #declare YELLOW = texture{ pigment{color rgb <0.7515625, 0.7515625, 0.1734375>} //crop corn colour finish{phong 0.8 ambient 0.3} } #declare CROP = texture{ pigment{color rgb <0.3815625, 0.3584375, 0.13875>} //crop ploughed colour finish{phong 0.8 ambient 0.3} } #declare LAKE = texture{ pigment{color rgb <0.23125, 0.346875, 0.578125>} //water blue finish{diffuse 0.3 ambient 0.3 phong .95} } #declare gleba_height = .002; // gleba is 5 mm above ground level #declare fr = 79.788456088; // radius of a 2-hectare gleba (in metres) #declare gleb = cylinder { <0, 0, 0>, <0, gleba_height, 0>, 1 // thin cylinder of unit radius texture { // define its texture that comprises: pigment { onion color_map { [0.0 color rgb <1, 1, 0, 0.5>] // starts at yellow, then blend through to [1.0 color rgb <0.815, 1.015, 0.51, 0.5>] // field-green rgb <0.8, 1.0, 0.5> } } finish { // with surface characteristics: diffuse 0.2 // diffusion ambient 0.5 // effective ambient lighting (brightness) } } translate <0, ground_level, 0> // move the gradiented circle down to ground level } #declare gleba = object { gleb scale } // rescale to the size of the 2-hectare gleba /* THREE-CIRCLE GLEBA ----------------------------------------------------------------------------- A gleba is deemed to be 2 hectares in area. That is 20,000 square metres. A three-circle gleba therefore comprises 3 touching circles, each of which has an area of two-thirds of a hectare. */ #declare mgr = sqrt(20000/(3*3.141592653)); //radius of each of the three circles #declare glebshift = mgr * (1/cosd(30)-1); // #declare minigleb = object { gleb scale //squash a 2-hectare circle to a third of its area clipped_by{cylinder{<0, -5, mgr>, <0, -3, mgr>, mgr}} translate <0, 0, glebshift> } #declare trigleb = union{ #declare k = 30; #while(k < 390) object{minigleb rotate <0, k, 0>} #declare k = k + 120; #end } /* 1-THE HEXAGONAL ROAD SYSTEM -------------------------------------------------------------------- Each of the 3 hexagons has an area, A = 1 hectare = 10,000 square metres. The perpenducular between the mid-point of each side of a hexagon and that hexagon's centre, hp = sqrt(A/(6*tand(30))) metres. Each side of each hexagon, hs = 2*sqrt(A/(6*tand(60))) metres. The points of each hexagon are rounded to a radius ir = 11.5 metres. Consequently, the length of the straight part of each side of a hexagon, hst = hs - 2*(ir-1)*Tan(30) = 31.744778112 metres. */ #declare A = 10000; //area of hexagon in square metres #declare hp = sqrt(A/(6*tand(30))); //perp between mid-point of side & centre of 1-hec hexagon #declare hs = 2*sqrt(A/(6*tand(60))); //total length of the side of a 1-hectare hexagon in metres #declare ir = 11.5; //radius of the rounded corners of the 1-hectare hexagons #declare ird = ir + ir; //diameter #declare hst = hs-2*(ir-1)*tand(30); //length of straight part of road forming side of hexagon #declare road_height = 0.008; //thickness of road material = 8 millimetres #declare circ_road = difference{ //create a circular road 2 metres wide cylinder{<0, 0, 0>, <0, road_height, 0>, ir} //and 5 mm high cylinder{<0, -.01, 0>, <0, 2*road_height, 0>, ir - 2 pigment{color rgbt<1,1,1,1>} //make this inner circle invisible } } #declare hex_side = union{ object{ circ_road clipped_by{box{<-ird, -1, 0>, <+ird, +1, ird>}} rotate <0,30,0> //clip out a 30 degree arc for rounded corner clipped_by{box{<0, -1,-ird>, <-ird, +1, ird>}} translate <0, 0, 1-ir> //move it from origin to island tangent. } box{<0, 0, -1>, } //path 2 metres wide, x metres long, 8 mm high translate<-hst/2, ground_level, hp> // Move side to ground level and to a position } /* such that the hexagon of which it would be a part is centred at the co-ordinate origin. */ #declare hex = union{ //i = 0 to 360 creates a full hexagon as in ../virtual/virtual.htm #declare i = 120; //i = 120 to 240 creates the 3-arm swastica form #while(i < 240) object{hex_side rotate <0,i,0>} //form a complete hexagon #declare i = i + 60; #end translate //set co-ordinate origin at } //one corner of the hexagon #declare ROAD = texture{ pigment{colour rgb <0.52, 0.49, 0.50>} //light grey tarmac. // light brown dirt track: Hex d1a346. 209.163.70 as used in ../virtual/virtual.htm // pigment{colour rgb <0.81640625, 0.63671875, 0.1796875>} finish{phong 0.8 ambient 0.4} } #declare roads = union{ //create the 3-hexagon landshare object{hex} //bounded by peripheral roads object{hex rotate <0,120,0>} object{hex rotate <0,240,0>} clipped_by{cylinder{<0, -5, 0>, <0, -3, 0>, fr}} //clipped hexagon texture{ROAD} } // 2) GARDEN AND LAKE ----------------------------------------------------------------------------- #declare island_height = .006; //height of island #declare shift = 1-ir*(1+1/cosd(30)); //shift from lake-centred to landshare-centred #declare lake_radius = 19.5; //radius of lake #declare island = union{ object{circ_road texture{ROAD}} cylinder{ //island in the centre of the circular road <0, 0, 0>, <0, island_height, 0>, ir - 2 texture{ //define its texture that comprises: pigment{color rgb <0.8, 1.0, 0.5>} //colour field-green rgb <0.8, 1.0, 0.5> finish { //with surface characteristics: diffuse 0.2 //diffusion ambient 0.31 //effective ambient lighting (brightness) } } } translate <0, ground_level, ir> } #declare lake_height = .004; //lake height 4mm above ground #declare lake = cylinder{ //THE LAKE (centred on centre of lake) <0, ground_level, 0>, <0, ground_level + lake_height, 0>, lake_radius //Lake 19.5 metres radius. } // ELLIPSOIDAL SILO ------------------------------------------------------------------------------- #declare esilo = sphere{ <0, 0, 0>, 2 scale <1, 4, 1> //ellipsoidal silo basic shape translate <0, -2, -lake_radius - 4> //translate it 1.25 times the radius of the island from origin } #declare silo_group = union{ object{esilo rotate <0, +30, 0>} object{esilo} object{esilo rotate <0, -30, 0>} texture{greene} //same material as the ninho } // CROP AND LAKE SECTORS -------------------------------------------------------------------------- #declare Sector1 = object{lake // 1-Lake texture{LAKE} translate<0,0,shift> rotate<0,-30,0> } #declare Sector2 = union{ // 2-Crop object{lake texture{YELLOW}} object{silo_group} translate<0,0,shift> rotate<0,-150,0> } #declare Sector3 = union{ // 3-Crop object{lake texture{CROP}} object{silo_group} translate<0,0,shift> rotate<0,-270,0> } #declare ownership = sphere{ //Ellipsoid of gradiented ownership <0, -4, 0>, fr scale<1, 1.5, 1> texture{pigment{color Col_Glass_General}} } /* OBJECTS -------------------- Dimensions in Metres ------------------------------------ The ninho module is constructed as a sphere of radius R and is then re-scaled to form a circular ellipsoid whose half-height is ½R at the very end of the program. The value of R is crucially determined by the resulting floor-to-ceiling clearance at the mid- point of the toroidal connecting corridors [see later]. */ #declare R = 8; //horizontal radius of the ellipsoidal module #declare s = 0.5; //scaling factor to squash to ellipseoid vertically #declare r1 = R * 0.5; //radius of outer circle of roof panels #declare h1 = R * cosd(30); //radius of the second flange 0.866025404R #declare r3 = 3 * R / 4; //off-set from central axis of droop-eye flange #declare h3 = R* sqrt(7/16); //radius of droop-eye flange 0.942809042R #declare rf = sqrt(R * R - 4); //radius of floor 1 real metre below centre-plane #declare sr = 1.5; //skylight radius #declare sd = sqrt(R*R - sr*sr); //skylight depth /* CREATE THE FLANGES FOR THE EDGES OF THE ELLIPTICAL CUT-OUTS The union below is of two thin co-axial cylindrical flanges 2 mm apart, with each flange 4 mm thick. The 2 mm separation is for a joining gasket of fibre or cork. The 3rd cylinder is used to cut out the centre of each cylinder to form a shallow 200 mm flange. When it is re-scaled at the very end of the program, each flange is squashed to half its size in the vertical (y-dimension) only. This makes the flange 10 cm wide on the major (horizontal) axis, reducing to 5 cm wide on the minor (vertical) axis. */ #declare a = 0.006; //6mm from the vertical plane between the two flanges #declare b = 0.002; //2mm from the vertical plane between the two flanges #declare c = 0.008; //to make the cutter 1mm proud of the flange cylinders #declare d = R + b; //to make cutter 1mm proud of sphere #declare f = 0.600; //600mm depth of flange #declare g = f + b; //602mm for cutters to clear the 600mm object being cut #declare w = 0.06; //thickness of the segment dividing walls #declare ww = 0.07; //thickness of dividing wall cutter /* For when illustrating flanges only: #declare a = 0.1; //from the vertical plane between the two flanges #declare c = 0.2; //to make the cutter 1mm proud of the flange cylinders */ /* DIVIDER: This is the flange of radius R (the radius of the sphere). It will be used to form the longitudinal segment dividers that radiate from the central skylight all the way round to the circular panel at the bottom of the sphere. */ #declare divider = difference{ cylinder{<0, 0, -w>, <0, 0, w>, R scale<1,s,1>} /* Form an elliptical cutting cylinder cylinder of the same radius but scaled to half in the x-dimension to make it elliptical so that it comes circular when the whole object is re-scaled at the end of the program. */ cylinder{<0, 0, -ww>, <0, 0, +ww>, (R - f) / 2 pigment{color rgbt<1,1,1,1>}} /* Similarly, form a transparent box to cut out a vertical strip to prevent the flanges from passing across the 3 metre diameter skylight. */ cylinder{<0, -d, 0>, <0, +d, 0>, sr pigment{color rgbt<1,1,1,1>}} scale<1, 1/s, 1> } #declare dividers = union{ #declare k = 0; //the circle of 6 yellow diamond-shaped panels #while(k < 360) object{divider rotate<0, k, 0>} #declare k = k + 60; #end texture{YELLOW} } #declare flange0 = difference{ //200 x 4 mm FLANGE, R METRES RADIUS union{ cylinder{<0, 0, -b>, <0, 0, -a>, R} //left 4mm thick cylinder cylinder{<0, 0, +b>, <0, 0, +a>, R} //right 4mm thick cylinder } /* Form a cylinder of radius 200mm less than the radius R of the sphere. Make this cylinder completely transparent (see pigment statement below). Unioning this transparent cylinder with the above pair of cylinders has the effect of cutting a big hole in the middle of them, thus leaving a pair of circular flanges 4mm thick and separated by 2mm. */ cylinder{<0, 0, -c>, <0, 0, +c>, R - f pigment{color rgbt<1,1,1,1>}} /* Similarly, form a transparent box to cut out a vertical strip to prevent the flanges from passing across the 3 metre diameter skylight. */ box{<-sr, -d, -c>, <+sr, +d, +c> pigment{color rgbt<1,1,1,1>}} } /* FLANGE 1: This is a circular flange of diameter h1 and is offset from the centre of the sphere horizontally by a distance r1. Thus 6 such flanges form cutting lines on the sphere, which are in the form of a Star of David. */ #declare flange1 = difference{ union{ cylinder{<0, 0, -b>, <0, 0, -a>, h1} //left flange cylinder cylinder{<0, 0, +b>, <0, 0, +a>, h1} //right flange cylinder } cylinder{<0, 0, -c>, <0, 0, +c>, h1 - f pigment{color rgbt<1,1,1,1>}} translate<0, 0, r1> //move the flange to its required radial position } /* FLANGE 2 is not used but this numbering is preserved in order to maintain the sense of symmetry in the geometry diagram geometry.png. */ /* FLANGE3: This is a circular flange of diameter h3 and is offset from the centre of the sphere horizontally by a distance r3. Thus 6 such flanges form cutting lines on the sphere, which are in the form of a Star of David. */ #declare flange3 = difference{ union{ cylinder{<0, 0, -b>, <0, 0, -a>, h3} //left flange cylinder cylinder{<0, 0, +b>, <0, 0, +a>, h3} //right flange cylinder } cylinder{<0, 0, -c>, <0, 0, +c>, h3 - f pigment{color rgbt<1,1,1,1>}} translate<0, 0, r3> //move the flange to its required radial position } /* FLANGE 4: This flange forms the outer roof circle. It surrounds and encloses the 6 squarish tile panels that surround the central skylight (see geometry.pn). Each of the outer and inner flanges is formed from solid cylinder whose centre is then removed by a transparent cutting cylinder. */ #declare flange4 = union{ difference{ cylinder{<0, 0, 0>, <0, -f, 0>, r1 + c hollow} cylinder{<0, b, 0>, <0, -g, 0>, r1 + b pigment{color rgbt<1,1,1,1>} hollow} } difference{ cylinder{<0, 0, 0>, <0, -f, 0>, r1 - b hollow} cylinder{<0, b, 0>, <0, -g, 0>, r1 - c pigment{color rgbt<1,1,1,1>} hollow} } translate <0, h1, 0> //translate from central horizontal plane to touch ellipse } /* FLANGE 5: This flange forms the inner roof circle. It surrounds and encloses the central 3- metre diameter skylight. Again, Each of the outer and inner flanges is formed from solid cylinder whose centre is then removed by a transparent cutting cylinder. */ #declare flange5 = union{ //FLANGE FOR INNER CIRCLE OF ROOF OF RADIUS sr difference{ cylinder{<0, 0, 0>, <0, -f, 0>, sr + c hollow} cylinder{<0, b, 0>, <0, -g, 0>, sr + b pigment{color rgbt<1,1,1,1>}} } difference{ cylinder{<0, 0, 0>, <0, -f, 0>, sr - b hollow} cylinder{<0, b, 0>, <0, -g, 0>, sr - c pigment{color rgbt<1,1,1,1>}} } translate <0, sd, 0> //translate to touch ellipse } /* CREATE THE TOROID-SECTION TO FORM THE CONNECTING PASSAGES BETWEEN THE SPHERICAL NODES. The minor radius of the torus = R, the radius of the main sphere. The major radius of the torus is the square root of (3 time R-squared). See torus_geom.png */ #declare T = torus{sqrt(3 * R * R), R} //create torus #declare C = cylinder{<0, 0, 0>, <0, -R/2, 0>, R} #declare passage = object{T //torus as basis for forming connecting passages /* Clip so only the required section of the central core of the torus remains */ clipped_by{object{C}} /* Rotate the torus 90 degrees around the x-axis so its central axis lies along the z-axis of the coordinate system. Next, move its central point along the z-axis to lie on the periphery of the main sphere. */ rotate<90, 0, 0> translate<0, 0, R> } /* Make floor for the connecting neck vertical cylinder clip it to fit the passage inside the torus passage. This cylinder can be conveniently made to be radius R (the radius of the main sphere). The floor is to be placed 1 metre below the equitorial plane of the ninho. However, a vertical scaling of s = 0.5 will be applied at the very end of the program to squash the sphere to an ellipsoid. Here, therefore, the floor must be set to 2 metres below the equitorial plane of the sphere. The floor is 300mm thick. Remember that, at this stage, the torus still lies at the coordinate origin around the horizontal plane with its central axis vertical (ie along the y-axis). */ #declare F = cylinder{<0, 0, 2>, <0, 0, 2.6>, R clipped_by{object{T inverse}} clipped_by{object{C}} rotate<90, 0, 0> translate<0, 0, R> } /* The floor-to-ceiling clearance is the crucial factor in determining the minimum value of R [refer to the diagram toriod_geom.png in the web article shell.htm]. The full external vertical half-height at the mid-point (thinnest part of the neck) of the interconnecting toroidal-section corridor h = s * (H - R) = s * R * tand(60) - R = s * R * (tand(60) - 1) = 0.5 * 8 * (1.732050808 -1) = 2.928203232 metres s is the vertical scaling factor, which rescales the whole dwelling unit to half height (to make the sphere of radius R a circular ellipsoid of horizontal radius R and total height R). Take 250cm off top and bottom for skin (flange) thickness. Corridor internal clearance half- height = 5.356406461 metres above and below the zero line (the zero horizontal plane). Floor level is 1 metre below the zero line. Total internal floor to ceiling clearance is therefore = 2.428203232 metres. Maximum ground clearance under the connecting corridors = (R / 2) - h = 4 - 2.928203232 = 1.071796768 metres. The path under the connecting bridges has to be lowered as much again below ground level to allow free passage of people under the bridge. */ /* Create an unsliced version of the ninho for quick rendering and for illustrations that appear prior to mention of the panels. */ #declare N = sphere{<0,0,0>, R hollow} //outer surface [replace this with the sphere/toroid object] #declare O = union{ object{N} object{object{T clipped_by{cylinder{<0, R/2, 0>, <0, -R/2, 0>, R}} rotate<90,0,0> translate<0,0,R>}} rotate<0,30,0> translate<-2*R,0,0> } #declare Plinth = object{object{T clipped_by{cylinder{<0, R/2, 0>, <0, 0, 0>, R}} translate<-2*R,0,0> translate<0,-R,0>}} #declare I = union{ //make a union of 6 node+corridor sections to form complete ninho #declare k = 30; #while(k<=390) object{O rotate <0,k,0>} // object{Plinth rotate <0,k,0>} #declare k = k + 60; #end scale<1,s,1> //scale to half height to make sphere into circular ellipsoid texture{greene} } // CREATE THE BASIC SPHERE WITH THE FLANGES IN PLACE ---------------------------------------------- #declare S = union{ //CREATE BASIC ELLIPSOID SHAPE FOR ACCOMMODATION MODULES object{N} //outer surface [replace this with the sphere/toroid object] #declare k = 0; #while(k<=180) //large elliptical flanges of longitude object{flange0 rotate <0,k,0>} #declare k = k + 60; #end #declare k = 30; #while(k<390) //smaller elliptical flanges marking the hexagon object{flange1 rotate <0,k,0>} object{flange3 rotate <0,k,0>} #declare k=k+60; #end object{flange4} //outer circle of the roof object{flange4 rotate<180,0,0>} //outer circle of the bottom object{flange5} //inner circle of the round skylight object{flange5 rotate<180,0,0>} //inner circle of the round bottom panel rotate<0,30,0> //rotate to correct orientation } /* TO ILLUSTRATE THE (EXAGGERATED) FLANGES ONLY --------------------------------------------------- union{ union{ object{flange4} //outer circle of the roof object{flange4 rotate<0,0,180>} //outer circle of bottom texture{pigment{color Cyan}} } union{ object{flange5} //inner circle of the roof round skylight object{flange5 rotate<0,0,180>} //inner circle of the bottom texture{pigment{color Pink}} } union{ #declare k = 30; #while(k<390) //small elliptical flanges marking the hexagon object{flange1 rotate <0,k,0>} object{flange3 rotate <0,k,0>} #declare k=k+60; #end texture{pigment{color Yellow}} } union{ #declare k = 0; #while(k<=180) //large elliptical flanges of longitude object{flange0 rotate <0,k,0>} #declare k=k+60; #end texture{pigment{color Magenta}} } scale<1,s,1> //squash it to form an ellipsoid } */ // CLIP BOXES USED IN CONSTRUCTING THE VARIOUS PANELS #declare cb1 = box{<-d, -d, r1>, } #declare cb2 = box{<-d, -d, r1>, } #declare cb3 = box{< 0, -d, -d>, } #declare cb4 = box{<-d, -d, -r1>, } #declare cb5 = box{<-d, -d, r3>, } #declare cb6 = box{<-d, -d, r1>, } #declare cb7 = box{<-d, -d, r3>, } // CUT UP THE SPHERE ALONG THE FLANGES ------------------------------------------------------------ /* Form a slice H of the sphere such that the slicing plane is at a distance r3 from the cental vertical axis of the sphere. Six such slices will fit around the sphere's circumference. This is the peripheral ellipsoidal cap from which the droop windows and their adjoining panels will be formed. */ #declare H = object{S clipped_by{object{cb7}}} /* Create the droop-eye window panel and then form 6 of them in a circle 60-degrees apart. */ #declare dew = object{H clipped_by{object{cb7 rotate<0,60,0>}} // rotate<0,-30,0> translate<0,0,4.0> rotate<0,30,0> //EXPLODE } #declare E = union{ #declare k = 0; #while(k < 360) object{dew rotate<0,k,0>} #declare k = k + 60; #end } /* Clip from H the panel sections which will go either side of each droop window. */ #declare htw = object{H clipped_by{object{cb5 rotate<0, 60,0>}} //clip the left edge clipped_by{object{cb5 rotate<0,-60,0>}} //clip the right edge } #declare Q1 = object{htw clipped_by{object{cb1 rotate<0,-60,0>}} //left of droop-eye // rotate<0,15,0> translate<0,0,4.0> rotate<0,-15,0> //EXPLODE } #declare Q2 = object{htw clipped_by{object{cb1 rotate<0, 60,0>}} //right of droop-eye // rotate<0,-15,0> translate<0,0,4.0> rotate<0,15,0> //EXPLODE } #declare H1 = union{object{Q1 texture{dm}} object{Q2 texture{lm}}} //make one pair one colour #declare H2 = union{object{Q1 texture{lm}} object{Q2 texture{dm}}} //other pair other colour /* Form the curved triangular panels T which fill in the gap in the periphery left by the panels that go each side of a droop-eye window. NOTE: panel T extends above and below the equator of the sphere. Then join them as a mirror pair, each of opposite colour. */ #declare T = object{S clipped_by{object{cb7}} clipped_by{object{cb2 rotate<0, 60,0>}} clipped_by{object{cb3}} // rotate<0,-5,0> translate<0,0,4.0> rotate<0,5,0> //EXPLODE } #declare DT = union{object{T texture{dm}} object{T texture{lm} rotate<180, 180, 0>}} /* Form the panels P, immediately above and below the triangular panels mentioned above. Then assemble a mirror pair, of opposite colours, side-by-side to form a double panel. */ #declare P = object{S clipped_by{object{cb6}} clipped_by{object{cb2 rotate<0, 60,0>}} clipped_by{object{cb3}} // rotate<0,-14,0> translate<0,0,2.0> rotate<0,14,0> //EXPLODE } #declare DP = union {object{P texture{lm}} object{P texture{dm} rotate<180, 180, 0>}} /* Place mirror pairs of these panels together to form an assembly which spans a third of the periphery of the sphere. */ #declare W = union { object{DP} //right-handed double side panel object{DP rotate<180, -120, 0>} //left-handed double side panel object{DT} //right-handed double side panel object{DT rotate<180, -120, 0>} //left-handed double side panel } /* Create a panel U in the shape of a one-sixth sector of a circular ring. Six of these will form the surround to the central circular skylight. A spherical cap of radius r1 is clipped out of the sphere S. Its centre section - the size of the central circular skylight - is then cut out using an invisible cylinder of diameter sr as a difference-cutter. A 60-degree sector is then clipped out of the remaining ring. No texture is applied at this stage. */ #declare U = object { difference { object{S clipped_by{cylinder{<0,-d, 0>, <0, d, 0>, r1}}} cylinder{<0,-d, 0>, <0, d, 0>, sr pigment{color rgbt<1,1,1,1>}} } clipped_by{object{cb3}} //clip to form a 60 degree segment rotate <0, 120, 0> clipped_by{object{cb3}} // rotate<0,30,0> translate<0,0,-1.0> rotate<0,-30,0> //EXPLODE } /* Form the diamond-shaped panel. Note: this cut includes both the top and bottom panel. A circle of 6 such panels is later generated to form the complete top and bottom circles. */ #declare V = object{S clipped_by{object{cb6}} rotate <0, 60, 0> clipped_by{object{cb6}} // rotate<0,-30,0> translate<0,0,3.0> rotate<0,30,0> //EXPLODE } #declare p1 = union{object{U} object{V} texture{dm}} #declare p2 = union{object{U} object{V} texture{lm}} /* Create the 6 little triangular skylight panels (hexagonal on outer edge, circular on inner edge). The sphere S is clipped across the flats of the hexagon formed by the 6 type-1 flanges. The resulting clip is rotated 60-degrees (to the next pair of flats of the hexagon) and clipped again. The circle (contained by the hexagon) of radius r1 is then cut out, leaving the 6 triangles. Note: the clipping box clips the sphere both top and bottom, thus creating a lower ring of 6 "skylights" below for ground observation and sensors. */ #declare K = object{ difference{ object{S clipped_by{object{cb4}} rotate<0,60,0> clipped_by{object{cb4}} rotate<0,60,0> clipped_by{object{cb4}} } cylinder{<0, -d, 0>, <0, d, 0>, r1 pigment{color rgbt<1,1,1,1>}} } } /* Unfortunately, in order to created an exploded view of the triangular skylights, it is necessary to cut out just one of them from the group, shift it outwards radially, and then reproduce it 6 times at intervals of 60 degrees around the circle. #declare J = object{K clipped_by{object{cb3}} rotate<0,120,0> clipped_by{object{cb3}} rotate<0,30,0> translate<0,0,-1.6> rotate<0,-30,0> //EXPLODE } #declare K = union{ #declare k = 0; //the circle of 6 yellow diamond-shaped panels #while(k < 360) object{J rotate<0, k, 0>} #declare k = k + 60; #end } //when not exploding, comment-out from "Unfortunately" to here */ //CREATE OBJECT FOR THE FLANGED CIRCULAR SKYLIGHT & FLANGED BOTTOM PANEL #declare B = object{S clipped_by{cylinder{<0, -d, 0>, <0, d, 0>, sr}}} #declare u1 = union{object{p1} object{H1} object{W}} #declare u2 = union{object{p2} object{H2}} /* CUT UP THE PASSAGE SECTION INTO PANELS. */ #declare q = d + d; #declare cb8 = box{<-q, -q, r1>, } #declare cb9 = box{<-q, -q, r3>, } #declare cb0 = box{<-q, -q, -r1>, } #declare cba = box{< 0, -q, -q>, } #declare cbb = box{<-q, -q, R>, } #declare Pa = object{passage clipped_by{object{cb8}}} //inner slice #declare Pb = object{passage clipped_by{object{cb9}}} //middle slice #declare P1 = object{Pb clipped_by{object{cb9} rotate<0,60,0>}} //middle panel #declare P2 = object{Pb clipped_by{object{cb8} rotate<0,60,0>}} //inner panel #declare P3 = object{Pa clipped_by{object{cb9} rotate<0,60,0>}} //middle panel #declare P4 = object{Pa clipped_by{object{cb8} rotate<0,60,0>}} //inner panel #declare P5 = object{Pa clipped_by{object{cb0} rotate<0,60,0>} clipped_by{object{cba}}} //middle #declare P6 = object{Pb clipped_by{object{cb0} rotate<0,60,0>} clipped_by{object{cba}}} //inner #declare P7 = object{Pa clipped_by{object{cbb} rotate<0,60,0>}} //middle panel #declare P8 = object{Pb clipped_by{object{cbb} rotate<0,60,0>}} //inner panel #declare psg = union{ //SEMI-CONNECTING PASSAGE object{P1 texture{dm}} object{P1 rotate<0,0,180> texture{lm}} object{P2 texture{lm}} object{P2 rotate<0,0,180> texture{dm}} object{P3 texture{lm}} object{P3 rotate<0,0,180> texture{dm}} object{P4 texture{dm}} object{P4 rotate<0,0,180> texture{lm}} object{P5 texture{lm}} object{P5 rotate<0,0,180> texture{dm}} object{P6 texture{GLASS}} object{P6 rotate<0,0,180> texture{GLASS}} object{P7 texture{GLASS}} object{P7 rotate<0,0,180> texture{GLASS}} object{P8 texture{lm}} object{P8 rotate<0,0,180> texture{dm}} object{F texture{lm}} //passage floor } /* CONSTRUCT THE FLOOR SECTION: the floor has to be installed 2 metres below the centre-plane of the sphere so that, when the sphere is squashed to half its height to form an ellipsoid, the floor will then be only 1 metre below the centre plane. */ #declare FLOOR = cylinder{ <0, 0, 0>, <0,-.15, 0>, rf //see geometry.png translate <0, -2, 0> //shift it vertically to floor level in sphere clipped_by{sphere{<0,0,0> R}} texture{YELLOW} //giving it the desired surface texture } // ------------------------ ASSEMBLE THE GENERIC SPHERICAL MODULE --------------------------------- #declare G = union{ union{ object{E} //the 6 droop-eye windows object{K} //the 6 little triangular skylights top and bottom (12 in all) object{B} //glass skylights (top and bottom) texture{GLASS} //all made of glass } union { //6 sectored panels top and 6 at bottom and #declare k = 0; //the circle of 6 yellow diamond-shaped panels #while(k < 360) object{u1 rotate<0, k, 0>} object{u2 rotate<0, k + 60, 0>} #declare k = k + 120; #end } object{dividers} //walls that divide the ellipsoidal space into segments object{FLOOR} } /* FORM A NINHO COMPONENT AS FOLLOWS. Take one panelled generic ellipsoid G. Slice off what is beyond two of the sides of the central triangle. [Note: this slicing off process is normally commented out because the result is always hidden and it saves a vast amount in rendering time.] Attach a panelled half-passage in place of the 2 lopped off parts of the ellipsoid. Move the completed module to its proper peripheral position to form part of the complete ninho (accommodation unit). */ // #declare cbc = box{, <-d,-d,-d>} #declare module = union{ object{G // clipped_by{cbc rotate<0, 60,0>} clipping suspended to save vastly on rendering time // clipped_by{cbc rotate<0,-60,0>} clipping suspended to save vastly on rendering time } object{psg} object{psg rotate<0, 120, 0>} rotate<0,30,0> translate<-2*R, 0, 0> } /* The following loop creates and joins together 6 component modules to form the complete hexagonal formation of the accommodation unit. Finally, the complete accommodation unit is squashed to half its height to make its nodes and passages ellipsoidal. */ #declare ninho = union{ #declare k = 30; #while(k < 390) object{module rotate<0, k, 0>} #declare k = k + 60; #end scale<1,s,1> } /* Construct and render the final scene. */ union{ // object{ninho} //the 6-node accommodation unit (sliced into panels) object{I} //the 6-node accommodation unit (unsliced) object{trigleb} //clover-leaf form of the gleba object{roads} //the three-way raos system of the gleba object{Sector1} //the lake (and island) object{Sector2} //first crop crescent object{Sector3} //second crop crescent // rotate<0,-105,0> //little rotation to kill the boring symmetry rotate<0,30,0> } /* Chop an ellipsoidal unit in half vertically to illustrate the segment dividing walls. union{ object{dividers} object{FLOOR} scale<1,s,1> rotate<0,14,0> } */