/* POV-RAY PROGRAM http://robmorton.20m.com/projects/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 -visual DirectColor toroid.pov +W320 +H240 Medium Frame: povray -visual DirectColor toroid.pov +W640 +H480 Large Frame: povray -visual DirectColor toroid.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 G = 1.6180339887; //The Godlden Ratio #declare oh = 280; //hypotenuse distance to observer: 100 normal 120 exploded #declare rd = 89.9; /*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.85, 1.0, 0.6>} finish{diffuse 0.2 ambient 0.5} } 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 dm1 = texture{pigment{color rgb<0.50, 0.52, 0.49>} finish{phong 0.8 ambient 0.5}} #declare dm2 = texture{pigment{color rgb<0.00, 0.60, 1.00>} finish{phong 0.8 ambient 0.5}} #declare GLASS = texture{pigment{color Col_Glass_General} finish{F_Glass8}} //a greenish glass would be better for the main shell and ribbs #declare TRANS = texture{pigment{color rgb<1,1,1,1>}} //transparent // GLEBA CIRCLE ----------------------------------------------------------------------------------- #declare YELLOW = texture { pigment { color rgb <0.90, 0.86, 0.32> } // crop corn colour finish { phong 0.8 ambient 0.4 } } #declare CROP = texture { pigment { color rgb <0.58, 0.55, 0.30> } // crop ploughed colour finish { phong 0.8 ambient 0.4 } } #declare LAKE = texture { pigment { color rgb <0.4, 0.7, 0.9> } // 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>} 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 ----------------------------------------------------------------------------- The average total arable area per person worldwide = 2396 square metres. There are two crop circles. Each circle must therefore have an area of 1198 square metres. Each circle must therefore have a radius of 19.527806934 metres. However, since the outer radius of the torus is 24 metres, I decided to make the radius of the crop circles the same. The area of each crop circle is therefore 1809.557368468 square metres, which is just over 51% larger than the 1198 square metres needed. This allows for the part of the circles that fall under the shadow of the torus. All the lakes in the world contain about 176400 cubic kilometres of fresh water. The habit- able land of the Earth is 130693000 square kilometres. If the habitable land were a lake, the water would have a depth of 176400/130693000 = 0.001349728 kilometres = 1.349728 metres. The size of the lake at 24 metres radius would have to have a depth of 36.810763323 metres in order to be representative of the individual's rightful share of the Earth's fresh water. For safety reasons, the lake is only one metre deep. It is therefore merely symbolic of the fact that fresh water area must be considered as part of the individual terrestrial inhabitant's rightful inheritance. */ #declare lake_radius = 24; //radius of lake same as torus. #declare shift = lake_radius/cosd(30); //shift from lake-centred to landshare-centred #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 24 metres radius. } /* ELLIPSOIDAL SILO, made of a 2 metre diameter by 8 metres high ellipsoidal shell, sunk 2 metres into the ground, and translated to just outside the circumferance of a lake centred at the centre of the gleba. */ #declare esilo = sphere{<0,0,0>, 2 scale <1,4,1> translate <0,0,lake_radius+4>} #declare sg = union{ object{esilo rotate <0, +30, 0>} object{esilo} object{esilo rotate <0, -30, 0>} texture{dm1} //same material as the ninho } // CROP AND LAKE SECTORS -------------------------------------------------------------------------- #declare Sector1 = object{lake texture{LAKE} translate<0,0,shift> rotate<0,30,0>} #declare Sector2 = union{ object{lake texture{YELLOW}} object{sg} translate<0,0,shift> rotate<0,150,0> } #declare Sector3 = union{ object{lake texture{CROP}} object{sg} 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}} } /* Put in the stone circle for the council fire at the very centre of the farmlet. The stone circle is 4 metres radius. */ #declare CounselFire = cylinder{ <0,ground_level,0>, <0,ground_level + 0.05,0>, 4 texture{pigment{colour rgb <0.76953125, 0.78125, 0.796875>} finish{phong 0.8 ambient 0.4}} } /* OBJECTS -------------------- Dimensions in Metres ------------------------------------ Form the torus shell. Define its major and minor radii (16 and 8 metres respectively). The top half of the shell is scaled to have a slightly larger vertical radius than the bottom half of the shell. The top half bulges 3 metres above the central zero plane, while the bottom half bulges only 2 metres below it. This makes the external maximum height of the shell 5 metres, while allowing a ground clearance of 2 metres. */ #declare h1 = 3; //height of top half-shell #declare h2 = 2; //height of bottom half-shell #declare r = h2 * 4; //minor horizontal radius of the torus 8 #declare R = r * 2; //major horizontal radius of the torus 16 #declare RL = 2; //half the radial length of support in metros #declare ang = 2; //angular width of support in degrees #declare d = R + R + 1; #declare delta = 5; //number of degrees short of 60 each side of inner module segment #declare CB = box{<-d,ground_level-1,0>, } //clip box #declare C1 = cylinder{<0,0,0>, <0,+4,0>, R+R} //top clip cylinder #declare C2 = cylinder{<0,0,0>, <0,-3,0>, R+R} //bottom clip cylinder /* Divide a 60 degree segment into the golden ratio. */ #declare ga = 60 / (G + 1); //minor golden section 22.917960675 degrees #declare gb = 60 - ga; //major golden section 37.082039325 degrees #declare Delta = ga/2; #declare DeltA = (gb-0.025)/2; /* Create the transparent outer torus shell with segment-shaped support legs*/ #declare T = union{ torus{R, r scale<1,h1/r,1> clipped_by{object{C1}}} //top half of torus torus{R, r scale<1,h2/r,1> clipped_by{object{C2}}} //bottom half of torus } #declare S = union{ object{T clipped_by{object{CB}} //clip out a 60-Delta degree segment clipped_by{object{CB rotate<0,120+Delta+Delta,0>}} } rotate<0,-Delta,0> } #declare N = union{ #declare i = 30; #while(i < 390) //6 supports object{S rotate<0,i,0>} #declare i = i + 60; #end texture{GLASS} } /* Create the supports for the outer torus. Make a cylinder. Cut out the middle to form an anulus. Cut out a sector of the anulus. Make 6 of them. */ #declare leg = intersection{ cylinder{<0,ground_level,0>, <0,-1.5,0>, R + RL} cylinder{<0,ground_level-1,0>, <0,2,0>, R - RL inverse} object{CB rotate<0,90-ang,0>} object{CB rotate<0,ang-90,0>} } /* Construct the ribbing which supports the inner modules within outer glass torus */ #declare rib = difference{ //main vertical cylindrical rib cylinder{<0, r * h1 / r - 0.025, 0>, <0, 0.025 - r * h2 / r, 0>, R + 0.25 texture{dm1}} cylinder{<0, r * h1 / r, 0>, <0, - r * h2 / r, 0>, R texture{TRANS}} } #declare beltrib = difference{ //main horizontal cylindrical rib cylinder{<0, 0.015, 0>, <0, -0.015, 0>, R + r - 0.025 texture{dm1}} cylinder{<0, 0.020, 0>, <0, -0.020, 0>, R - r + 0.025 texture{TRANS}} } #declare Rib = difference{ difference{ object{T} object{CB rotate<0,Delta,0>} //the ribs are 2 degrees wide } object{CB rotate<0,180-Delta,0>} rotate<0,180,0> } #declare Ribs = union{ #declare i = 0; #while(i < 360) //6 supports object{Rib rotate<0,i+30,0>} object{leg rotate<0,i,0>} #declare i = i + 60; #end texture{dm1} } /* Create an inner torus that is half a metre less all round. Note that this will not be a torus with the same vertical to horizontal radii ratio as the outer one. */ #declare w = 0.5; //wall thickness = half a metre #declare ri = r - 0.5; //minor radius of the inner torus #declare hi1 = h1 - 0.5; //vertical radius of the top half of the inner torus #declare hi2 = h2 - 0.5; //vertical radius of the bottom half of the inner torus #declare q = 1.8; //bulge depth of end caps #declare ang = 14; //half-angle subtended by skylight #declare UEC = sphere{<0,0,0>, ri scale<1,hi1/ri,q/ri>} //upper end-cap ellipsoid #declare LEC = sphere{<0,0,0>, ri scale<1,hi2/ri,q/ri>} //lower end-cap ellipsoid #declare E = union{ //create a single end-cap from the two half-ellipsoids object{UEC clipped_by{cylinder{<0,0,0>, <0,+4,0>, R+R}}} object{LEC clipped_by{cylinder{<0,0,0>, <0,-3,0>, R+R}}} clipped_by{object{CB}} } #declare UIT = torus{R, ri scale<1,hi1/ri,1>} //complete upper inner torus #declare LIT = torus{R, ri scale<1,hi2/ri,1>} //complete lower inner torus #declare U = union{ //create a complete segment with end-caps but without floor union{ object{UIT clipped_by{object{C1}}} //top half of inner torus object{LIT clipped_by{object{C2}}} //bottom half of inner torus clipped_by{object{CB rotate<0,150+delta,0>}} //clip out a 60-delta degree segment clipped_by{object{CB rotate<0, 30-delta,0>}} } object{E translate rotate<0,delta-30,0>} //add its half-ellipsoidal end caps object{E rotate<0,180,0> translate rotate<0,30-delta,0>} texture{dm1} //colour for inner segments } /* Construct the skylights. These are segments of the torus. They are constructed by the same process as the support plinths were constructed. */ #declare SL = intersection{ //skylight cylinder{<0,h2-0.5,0>, <0,h1,0>, R - 0.03} cylinder{<0,h2-0.6,0>, <0,h1+0.5,0>, R - 2.03 inverse} object{CB rotate<0,180-DeltA,0>} object{CB rotate<0,DeltA,0>} } #declare SLI = union{ //form the merged group of skylights #declare i = 0; #while(i < 360) object{SL rotate<0,i,0>} #declare i = i +60; #end texture{TRANS} //completely transparent } #declare I = merge{ //form the merged group of inner accommodation modules // object{Ribs} // object{rib} // object{beltrib} #declare i = 0; #while(i < 360) object{U rotate<0,i,0>} #declare i = i +60; #end object{SLI} } /* The floor for the whole of the ninho must be constructed separately using the "union{}" function and not the "merge{}" function. This is to make sure the floors actually join up across the inter-segment door openings. First create a large thin cylinder FC from which to cut out all the floor components. */ #declare FC = cylinder{<0,-1.1,0>, <0,-1,0> R+R} //thin annulus to cut out bits from #declare ECF = object{FC clipped_by{object{LEC} translate}} //end-cap floor #declare SF = union{ //complete segment floor object{FC //floor annulus clipped_by{object{LIT}} //bottom inner torus clipped_by{object{CB rotate<0,150+delta,0>}} //clip out a 60-delta degree segment clipped_by{object{CB rotate<0, 30-delta,0>}} } object{ECF rotate<0,delta-30,0>} //end-cap floor left object{ECF rotate<0,30-delta,0>} //end-cap floor right } #declare F = union{ //form the merged group of inner accommodation modules #declare i = 0; #while(i < 360) object{SF rotate<0,i,0>} #declare i = i +60; #end texture{dm2} } /* Construct and render the final scene. */ union{ union{ // object{N} //outer glass torus object{I} //inner opaque torus object{F} //floors clipped_by{cylinder{<0,ground_level,0>, <0,0,0>, R+R}} //for floor plan } object{trigleb} //clover-leaf form of the gleba object{roads} //the three-way roads system of the gleba object{Sector1} //the lake object{Sector2} //first crop crescent object{Sector3} //second crop crescent object{CounselFire} // rotate<0,15,0> //little rotation to kill the boring symmetry 15 // translate<0,0,-4.5> }