POV-Ray : Newsgroups : povray.text.scene-files : Bumpy CSG-sphere Server Time
31 Oct 2024 12:15:13 EDT (-0400)
  Bumpy CSG-sphere (Message 1 to 1 of 1)  
From: Tor Olav Kristensen
Subject: Bumpy CSG-sphere
Date: 31 Mar 2000 20:24:36
Message: <38E54FA5.98071D16@hotmail.com>
Here is the code for an image I posted
31. March in povray.binaries.images 

Tor Olav

// =====================================================================
//
// Copyright 2000 by Tor Olav Kristensen.
//
// mailto:tor### [at] hotmailcom
// http://www.crosswinds.net/~tok/tokrays.html
//
// =====================================================================
// 
// Sphere with smooth bumps made with CSG (spheres, toruses and cones)
// The bumps are placed in the middle of the pentagons and hexagons 
// of a Buckminsterfullerene. 
// (See the web page above for images of Buckminsterfullerenes.)
// 
// =====================================================================

#version 3.1;

#include "colors.inc"
#include "textures.inc"

#declare Origo = <0, 0, 0>;

// =====================================================================

// Just some of my old macros

#macro Pythagoras(hyp, kat)

  sqrt(vdot(<hyp, -kat>, <hyp, kat>)) 
  
#end // macro Pythagoras


/* // Not needed here right now
#macro Cosinus(aa, bb, cc)
  
  (vdot(<aa, bb, -cc>, <aa, bb, cc>)/(2*aa*bb))

#end // macro Cosinus
*/


// The next macro returns two angles (stored in a vector)
// The first is the angle between Vector and the Y-axis
// The second is the angle between the projection
// of Vector to the XZ-plane and the X-axis

#macro VectorAngles(Vector)

  <acos(vnormalize((x+z)*Vector).x)*(Vector.z < 0 ? -1 : 1), 
   acos(vnormalize(Vector).y), 
   0>
  
#end // macro VectorAngles


// This macro returns the object; Thing, "tilted" in the 
// direction of the vector; TiltVector

#macro vtilt(Thing, TVector)

  #local RotateAngles = VectorAngles(TVector);

  object {
    Thing
    rotate  degrees(RotateAngles.x)*y
    rotate -degrees(RotateAngles.y)*z 
    rotate -degrees(RotateAngles.x)*y
  }

#end // macro vtilt

// =====================================================================

// I used the points below to find suitable locations
// for my bumps.

// To make a "Buckyball" with them, just make 12 cylinder-
// pentagons from 5 and 5 subsequent points in the array.

#declare NrOfBuckyPts = 60;

#declare BuckyArray =
array[NrOfBuckyPts] {
  < 2.226730,  0.594920,  2.684200>,
  < 3.134080,  0.161810,  1.635440>,
  < 3.250250,  1.240130,  0.668290>,
  < 2.414560,  2.339640,  1.119120>,
  < 1.782170,  1.940950,  2.364960>,
  < 1.342130, -0.311850,  3.256820>,
  <-0.027000,  0.086540,  3.535890>,
  <-0.890470, -1.048410,  3.257750>,
  <-0.054970, -2.148180,  2.806770>,
  < 1.324810, -1.692910,  2.806120>,
  < 3.117650, -1.159560,  1.204400>,
  < 2.193000, -2.107290,  1.802560>,
  < 1.720910, -2.995760,  0.754440>,
  < 2.353890, -2.597090, -0.491290>,
  < 3.216930, -1.462050, -0.213260>,
  < 3.345290,  0.950710, -0.688050>,
  < 3.328380, -0.430390, -1.138540>,
  < 2.581820, -0.487170, -2.383660>,
  < 2.137050,  0.858790, -2.702690>,
  < 2.608990,  1.747420, -1.654660>,
  < 1.709970,  3.101980,  0.194250>,
  < 1.809270,  2.799410, -1.223290>,
  < 0.501490,  3.010120, -1.820490>,
  <-0.406030,  3.443130, -0.771880>,
  < 0.340880,  3.499990,  0.473170>,
  < 0.472290,  2.321910,  2.631870>,
  <-0.264220,  3.118480,  1.665080>,
  <-1.643750,  2.662990,  1.665550>,
  <-1.759930,  1.585190,  2.632880>,
  <-0.452190,  1.374270,  3.230230>,

  <-2.230680, -0.584280, -2.701320>,
  <-3.138380, -0.151090, -1.652660>,
  <-3.254550, -1.228980, -0.685460>,
  <-2.418840, -2.328500, -1.136370>,
  <-1.785970, -1.930080, -2.382100>,
  <-1.346280,  0.322850, -3.273640>,
  < 0.023000, -0.074940, -3.552420>,
  < 0.885930,  1.060390, -3.274220>,
  < 0.049970,  2.159870, -2.823390>,
  <-1.329630,  1.704060, -2.823020>,
  <-3.122300,  1.170370, -1.221530>,
  <-2.197990,  2.118350, -1.819620>,
  <-1.725990,  3.007160, -0.771470>,
  <-2.358450,  2.608490,  0.474240>,
  <-3.221550,  1.473440,  0.196030>,
  <-3.349590, -0.938890,  0.670910>,
  <-3.332630,  0.442150,  1.121470>,
  <-2.585870,  0.499300,  2.366750>,
  <-2.141500, -0.846500,  2.686090>,
  <-2.613600, -1.735240,  1.637920>,
  <-1.714530, -3.090350, -0.211190>,
  <-1.814140, -2.787320,  1.206480>,
  <-0.506670, -2.998220,  1.803800>,
  < 0.400930, -3.431500,  0.755070>,
  <-0.345460, -3.488360, -0.490180>,
  <-0.475910, -2.310710, -2.648970>,
  < 0.260190, -3.107130, -1.682110>,
  < 1.639710, -2.651480, -1.682710>,
  < 1.756120, -1.573340, -2.649740>,
  < 0.448510, -1.362650, -3.246970>
}


// Not needed for this scene. 
// This array contains information about how to select pairs 
// of points in the BuckyArray that are to be used as endpoints 
// in e.g. cylinders so that they ties the pentagons together.
/* 
#declare OtherLines =
array[30][2] {
  { 00, 05 }, { 01, 10 }, { 02, 15 }, { 03, 20 }, { 04, 25 },
  { 09, 11 }, { 14, 16 }, { 19, 21 }, { 24, 26 }, { 29, 06 },
  { 35, 30 }, { 40, 31 }, { 45, 32 }, { 50, 33 }, { 55, 34 },
  { 39, 41 }, { 44, 46 }, { 49, 51 }, { 54, 56 }, { 59, 36 },
  { 07, 48 }, { 12, 53 }, { 17, 58 }, { 22, 38 }, { 27, 43 },
  { 08, 52 }, { 13, 57 }, { 18, 37 }, { 23, 42 }, { 28, 47 }
}
*/


// If you like to make the hexagons in a "Buckyball instead 
// of pentagons, then you need this information. 
// Just use the array below to look up which pair of points 
// in the BuckyArray to use for the cylinders.
// Note that if you render all of them, then some of the 
// cylinders will "double" 

#declare Hexagons = 
array [20][6][2] {
  { { 00,05 }, { 05,09 }, { 09,11 }, { 11,10 }, { 10,01 }, { 01,00 } },
  { { 01,10 }, { 10,14 }, { 14,16 }, { 16,15 }, { 15,02 }, { 02,01 } },
  { { 02,15 }, { 15,19 }, { 19,21 }, { 21,20 }, { 20,03 }, { 03,02 } },
  { { 03,20 }, { 20,24 }, { 24,26 }, { 26,25 }, { 25,04 }, { 04,03 } },
  { { 04,25 }, { 25,29 }, { 29,06 }, { 06,05 }, { 05,00 }, { 00,04 } },
  
  { { 09,08 }, { 08,52 }, { 52,53 }, { 53,12 }, { 12,11 }, { 11,09 } },
  { { 14,13 }, { 13,57 }, { 57,58 }, { 58,17 }, { 17,16 }, { 16,14 } },
  { { 19,18 }, { 18,37 }, { 37,38 }, { 38,22 }, { 22,21 }, { 21,19 } },
  { { 24,23 }, { 23,42 }, { 42,43 }, { 43,27 }, { 27,26 }, { 26,24 } },
  { { 29,28 }, { 28,47 }, { 47,48 }, { 48,07 }, { 07,06 }, { 06,29 } },
  
  { { 30,35 }, { 35,39 }, { 39,41 }, { 41,40 }, { 40,31 }, { 31,30 } },
  { { 31,40 }, { 40,44 }, { 44,46 }, { 46,45 }, { 45,32 }, { 32,31 } },
  { { 32,45 }, { 45,49 }, { 49,51 }, { 51,50 }, { 50,33 }, { 33,32 } },
  { { 33,50 }, { 50,54 }, { 54,56 }, { 56,55 }, { 55,34 }, { 34,33 } },
  { { 34,55 }, { 55,59 }, { 59,36 }, { 36,35 }, { 35,30 }, { 30,34 } },
  
  { { 39,38 }, { 38,22 }, { 22,23 }, { 23,42 }, { 42,41 }, { 41,39 } },
  { { 44,43 }, { 43,27 }, { 27,28 }, { 28,47 }, { 47,46 }, { 46,44 } },
  { { 49,48 }, { 48,07 }, { 07,08 }, { 08,52 }, { 52,51 }, { 51,49 } },
  { { 54,53 }, { 53,12 }, { 12,13 }, { 13,57 }, { 57,56 }, { 56,54 } },
  { { 59,58 }, { 58,17 }, { 17,18 }, { 18,37 }, { 37,36 }, { 36,59 } }
}


// Find and store the points in the middle of each of the 12 pentagons

#declare NrOfPents = 12; // Number of pentagons
#declare PentagonMids = array[NrOfPents] 

#declare Counter = 0;

#while (Counter < NrOfPents)
  #declare Cnt = Counter*5;
  #declare PentagonMids[Counter] = 
    (BuckyArray[Cnt + 00] +
     BuckyArray[Cnt + 01] +
     BuckyArray[Cnt + 02] +
     BuckyArray[Cnt + 03] +
     BuckyArray[Cnt + 04])/5;
  #declare Counter = Counter+1;
#end // while


// Find and store the points in middle of each of the hexagons

#declare NrOfHexs = 20; // Number of hexagons
#declare HexagonMids = array[NrOfHexs] 

#declare Counter = 0;
#while (Counter < NrOfHexs)
  #declare HexagonMids[Counter] = 
    (BuckyArray[Hexagons[Counter][0][0]] +
     BuckyArray[Hexagons[Counter][1][0]] +
     BuckyArray[Hexagons[Counter][2][0]] +
     BuckyArray[Hexagons[Counter][3][0]] +
     BuckyArray[Hexagons[Counter][4][0]] +
     BuckyArray[Hexagons[Counter][5][0]])/6;
  #declare Counter = Counter+1;
#end // while

#undef Hexagons

#undef BuckyArray


// Now copy all these point into a new matrix vOut (vector Out)
// Also make the length of all of these vectors equal to 1
// ( Don't mind me mixing up points and vectors :] )

#declare vNr = NrOfPents + NrOfHexs;
#declare vOut = array[vNr]


#declare Counter = 0;
#while (Counter < NrOfPents)
  #declare vOut[Counter] = vnormalize(PentagonMids[Counter]);
  #declare Counter = Counter+1;
#end // while


#declare Counter = 0;
#while (Counter < NrOfHexs)
  #declare vOut[NrOfPents + Counter] = vnormalize(HexagonMids[Counter]);
  #declare Counter = Counter+1;
#end // while

// =====================================================================

// Try experimenting with these values

// (I haven't had time to make the geometry and CSG below "robust"
// so you may get strange/wrong results with some values.)

#declare MSC = Origo; // Main Sphere Center

#declare R1 = 12;  // For the main sphere
#declare R2 = 1.5; // For the edges around the bumps (toruses minor) 
#declare R3 = 3;   // For the bottoms of the bumps (small spheres)

// =====================================================================

// First some geometry calculations


// (I should have added or subtracted the dd value below from
// some of the values below, just to make differences in the 
// CSG's correct, but the scene rendered ok, so I have not done 
// this yet.)

#declare dd = 0.0001;

#declare EE = (pow(R2, 2)/2 + R3*(R1 + R2))/R1;
#declare FF = R1 - EE;
#declare GG = Pythagoras(R2 + R3, EE);
#declare OO = R1*GG/FF;
#declare PP = R1*GG/EE;

// Some other geometrical values that I might need later for 
// making the geometry and CSG tolerate all legal combinations
// of R1, R2 and R3
/*
#declare QQ = R1/(R1 - R3); 
#declare RR = R2/(R2 + R3); 
#declare JJ = FF*QQ;
#declare II = GG*QQ;
#declare KK = EE*RR;
#declare LL = GG*RR;
#declare MM = R1 - KK;
#declare NN = R1 - R2;
*/

// =====================================================================

// And then the CSG (Constructive Solid Geometry)


// First take a sphere and cut out of it some conical holes for the
bumps

#declare vCnt = 0;

#declare MainSphere =
difference {
  sphere { MSC, R1 }
  #while (vCnt < vNr)
    cone { MSC, 0, MSC + R1*vOut[vCnt], OO }
/* // Just a helping "line" to see the real size of the bump
    object { 
      vtilt(torus { II 0.3 }, vOut[vCnt]) 
      translate MSC + JJ*vOut[vCnt]
    }
*/
    #declare vCnt = vCnt+1;
  #end // while
}


// Then model all the smooth edges around the holes with some cut
toruses

#declare vCnt = 0;

#declare TorusParts =
merge {
  #while (vCnt < vNr)
    difference {
      object { 
        vtilt(torus { GG, R3 }, vOut[vCnt])
        translate MSC + FF*vOut[vCnt]
      }
      cone { MSC, PP, MSC + R1*vOut[vCnt], 0 }
      cone { MSC, 0, MSC + R1*vOut[vCnt], OO inverse }
    }
    #declare vCnt = vCnt+1;
  #end // while
}


// Make the bottoms of the bumps by subtracting spheres from some cones.
// Maybe I should have chosen to cut from a cylinder instead of cones,
// but it's too late to try that for this posting.

#declare vCnt = 0;

#declare SphereHoles =
merge {
  #while (vCnt < vNr)
    difference {
      union {
        cone { MSC + FF*vOut[vCnt], GG, MSC + R1*vOut[vCnt], 0 }
        cone { MSC, OO, MSC + R1*vOut[vCnt], 0 }
      }
      sphere { MSC + R1*vOut[vCnt], R2 }
    }
    #declare vCnt = vCnt+1;
  #end // while
}


// Attempt to make the interior of the sphere complete in case I 
// wanted to cut in it. But I think there is something wrong here. 
// So don't look inside my bumpy sphere ;)

#declare vCnt = 0;

#declare FillCones = 
merge {
  #while (vCnt < vNr)
    cone { MSC, 0, MSC + FF*vOut[vCnt], GG }
    #declare vCnt = vCnt+1;
  #end // while
}

// =====================================================================

// Assemble it all

merge {
  object { MainSphere }
  object { SphereHoles }
  object { TorusParts }
//  object { FillCones }
  texture { Soft_Silver }
  bounded_by { sphere { MSC, R1 + dd } }
}

// =====================================================================

// Then do the things I know little about

sky_sphere {
 pigment  {
  bozo 
  turbulence 0.6
  octaves 6
  omega 0.7
  lambda 2
  color_map {
   [0.0 color rgb < 0.0, 0.0, 0.9>]
   [0.3 color rgb < 0.2, 0.2, 0.9>]
   [1.0 color rgb < 0.9, 0.9, 0.9>]
  }
  scale < 1, 0.3, 2>
  rotate 120*y
 }
}

plane { 
  y, -80 
  pigment { Blood_Marble scale 800 }
}

// =====================================================================

// Let loose some light-rays

light_source { <-1000,  1000,  100 >, White/2 }
light_source { <  800,   200,  1000>, White/2 }
light_source { <-1200, 10000,  1000>, White/2 }

// and then try to catch some of them

camera {
  location <12, 0, -10>*2
  look_at MSC
}

// =====================================================================


Post a reply to this message

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