|
|
Here is the source code for an image I posted 18. April to the
povray.binaries.images newsgroup.
Note that some of the macros below are my "work in progress" and
therefore they may not be optimal or without errors.
There are some "noise" inside the "horns" of the green shapes.
I'm not sure what causes this, but I suspect that it is caused by
either:
A CSG operation with coinciding surfaces
- or -
That I have not used the keyword sturm in the torii declarations
- or -
By the strange behaviour of the torus shape when the minor radius is
greater than the major radius.
The latter can be seen when such a torus is subtracted from another
shape in a CSG operation. (This behaviour can be exploited if one
wish to make "concave cylinders" or "cigars".)
Tor Olav
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2000 by Tor Olav Kristensen
// mailto:tor### [at] hotmailcom
// http://www.crosswinds.net/~tok/tokrays.html
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#version 3.1;
#include "colors.inc"
#include "textures.inc"
//#include "finish.inc"
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Some constants
//#declare v2Null = <0, 0>;
#declare v2Origo = <0, 0>;
//#declare v2Units = <1, 1>;
#declare v3Null = <0, 0, 0>;
#declare v3Origo = <0, 0, 0>;
#declare v3Units = <1, 1, 1>;
#declare nothing = 1/10000;
//#declare smaller = 1 - nothing;
//#declare bigger = 1 + nothing;
#declare PtsInCube = 8;
#declare Cube =
array[PtsInCube] {
< 1, -1, 1>, <-1, -1, 1>, <-1, -1, -1>, <1, -1, -1>,
< 1, 1, 1>, <-1, 1, 1>, <-1, 1, -1>, <1, 1, -1>
}
#declare CornerCnt = 0;
#while (CornerCnt < PtsInCube)
#declare Cube[CornerCnt] = vnormalize(Cube[CornerCnt]);
#declare CornerCnt = CornerCnt + 1;
#end // while
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Start of macro declarations
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro v2Dir(v2D, vBasis1, vBasis2)
(v2D.x*vBasis1 + v2D.y*vBasis2)
#end // macro v2Dir
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro VectorAngles(Vector)
<acos(vnormalize((x+z)*Vector).x)*(Vector.z < 0 ? -1 : 1),
acos(vnormalize(Vector).y),
0>
#end // macro VectorAngles
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#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
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro Pythagoras(hyp, kat)
sqrt(hyp*hyp - kat*kat)
#end // macro Pythagoras
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro Cosinus(aa, bb, cc)
((aa*aa + bb*bb - cc*cc)/(2*aa*bb))
#end // macro Cosinus
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro vCosSin(aa, bb, cc)
#local Cos = (aa*aa + bb*bb - cc*cc)/(2*aa*bb);
#local Sin = sqrt(1 - Cos*Cos);
<Cos, Sin>
#end // macro vCosSin
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro ExCircle(aa, bb, cc)
#local vCS = vCosSin(aa, bb, cc);
(<aa, bb*vCS.y + vCS.x/vCS.y*(vCS.x*bb - aa)>/2)
#end // macro ExCircle
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro CirclesTouch(Type, R1, R2, R3, Dist,
CirIntSct, Ctr3, TouchPt13, TouchPt23,
Ctr45, Rad45)
#switch (Type)
#case (1)
#local Ra = R1 + R3;
#local Rc = R2 + R3;
#break // case
#case (2)
#local Ra = R1 - R3;
#local Rc = R2 - R3;
#break // case
#case (3)
#local Ra = R1 + R3;
#local Rc = R2 - R3;
#break // case
#case (4)
#local Ra = R1 - R3;
#local Rc = R2 + R3;
#break // case
#else
#debug "Macro CirclesTouch: Wrong Type number given."
#end // switch Type
#local vABC = vCosSin(Ra, Dist, Rc);
#local vRBR = vCosSin(R1, Dist, R2);
//#local Ctr1 = v2Origo;
#local Ctr2 = <Dist, 0>;
#declare Ctr3 = Ra*vABC;
#declare CirIntSct = R1*vRBR;
#declare TouchPt13 = R1*vABC;
#declare TouchPt23 = Ctr2 + R2/Rc*(Ctr3 - Ctr2);
#local sDir = ExCircle(vlength(CirIntSct - TouchPt13),
vlength(TouchPt23 - CirIntSct),
vlength(TouchPt13 - TouchPt23));
#local MidPt = (TouchPt13 + CirIntSct)/2;
#local vCtr = vnormalize(<vABC.y, -vABC.x > - <vRBR.y, -vRBR.x>)*
sDir.y;
#switch (Type)
#range (1, 2)
#declare Ctr45 = MidPt + vCtr;
#break // range
#range (3, 4)
#declare Ctr45 = MidPt - vCtr;
#break // range
#else
#debug "Macro CirclesTouch: Wrong Type number given."
#end // switch Type
#declare Rad45 = vlength(sDir);
#end // macro CirclesTouch
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro CSGselect(Type, MnThing1, MnThing2, MtThing, SmThing)
intersection {
object { MtThing }
object { SmThing inverse }
#switch (Type)
#case (1)
object { MnThing1 inverse }
object { MnThing2 inverse }
#break // case
#case (2)
object { MnThing1 }
object { MnThing2 }
#break // case
#case (3)
object { MnThing1 inverse }
object { MnThing2 }
#break // case
#case (4)
object { MnThing1 }
object { MnThing2 inverse }
#break // case
#else
#debug "Macro CSGselect: Wrong Type number given."
#end // switch Type
}
#end // macro CSGselect
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
#macro BetweenToruses(Type,
v3TCtr1, v3TCtr2,
R1b, R2b, R1s, R2s,
R3s,
v3Ctr3_a, v3Ctr3_b,
R3b_a, R3b_b,
oBetwO, oBetwI)
#local v3Diff = v3TCtr2 - v3TCtr1;
#local sTs = vlength(v3Diff);
#local rDiff = R2b - R1b;
#local v2TT = <sTs, rDiff>;
#local Distance = vlength(v2TT);
#local v3Forw = vnormalize(v3Diff);
#local v2Isect = v2Origo;
#local v2Ctr3 = v2Origo;
#local v2Touch1 = v2Origo;
#local v2Touch2 = v2Origo;
#local v2CtrA = v2Origo;
#local RadA = 0;
CirclesTouch(Type, R1s, R2s, R3s,
Distance, v2Isect, v2Ctr3, v2Touch1, v2Touch2,
v2CtrA, RadA)
#local v2Forw = vnormalize(v2TT);
#local v2Side = <-v2Forw.y, v2Forw.x>;
#declare v2Ctr3_a = v2Dir(v2Ctr3, v2Forw, v2Side);
#declare v2Ctr3_b = v2Dir(v2Ctr3, v2Forw, -v2Side);
#local v2CtrM_a = v2Dir(v2CtrA, v2Forw, v2Side);
#local v2CtrM_b = v2Dir(v2CtrA, v2Forw, -v2Side);
#local Obj1 =
object {
vtilt(torus { R1b, R1s }, v3Forw)
translate v3TCtr1
}
#local Obj2 =
object {
vtilt(torus { R2b, R2s }, v3Forw)
translate v3TCtr2
}
#local v3CtrM_a = v3TCtr1 + v2Dir(v2CtrM_a, v3Forw, v3Null);
#local v3CtrM_b = v3TCtr1 + v2Dir(v2CtrM_b, v3Forw, v3Null);
#local RMb_a = R1b + v2CtrM_a.y;
#local RMb_b = R1b + v2CtrM_b.y;
#declare v3Ctr3_a = v3TCtr1 + v2Dir(v2Ctr3_a, v3Forw, v3Null);
#declare v3Ctr3_b = v3TCtr1 + v2Dir(v2Ctr3_b, v3Forw, v3Null);
#declare R3b_a = R1b + v2Ctr3_a.y;
#declare R3b_b = R1b + v2Ctr3_b.y;
#local ObjM_a =
object {
vtilt(torus { RMb_a, RadA }, v3Forw)
translate v3CtrM_a
}
#local Obj3_a =
object {
vtilt(torus { R3b_a, R3s }, v3Forw)
translate v3Ctr3_a
}
#local ObjM_b =
object {
vtilt(torus { RMb_b, RadA }, v3Forw)
translate v3CtrM_b
}
#local Obj3_b =
object {
vtilt(torus { R3b_b, R3s }, v3Forw)
translate v3Ctr3_b
}
#declare oBetwO =
CSGselect(Type, Obj1, Obj2, ObjM_a, Obj3_a)
#declare oBetwI =
CSGselect(Type, Obj1, Obj2, ObjM_b, Obj3_b)
#end // macro BetweenToruses
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// End of macro declarations
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Initialization of some variables before the macro is called
// "CalcMacro" = Value to be Calculated by Macro
#declare Oouter = sphere { v3Origo, 1 }
#declare Oinner = sphere { v3Origo, 1 }
// It doesn't matter which shape Oouter and Oinner are set to
// Data for the "Rounding" torii.
// Try different values for RadiusMinorRnd
#declare RadiusMinorRnd = 1.0; // Rounding off radius
#declare RadiusMajorRndA = 0; // CalcMacro
#declare CenterRndA = v3Origo; // CalcMacro
#declare RadiusMajorRndB = 0; // CalcMacro
#declare CenterRndB = v3Origo; // CalcMacro
// Data for the torii that "meets"
// Major radius = 0 means that it is a sphere (not a torus)
// The outer sphere
#declare RadiusMinorOuter = 5.5;
#declare RadiusMajorOuter = 0;
#declare CenterOuter = v3Origo;
// The inner sphere
#declare RadiusMinorInner = 2.2;
#declare RadiusMajorInner = 0;
#declare CenterInner = CenterOuter;
#declare SpokeRadius = 0.2; // For "spokes" at the thinnest
// The torus for used in the making of a "spoke"
#declare RadiusMajorSpkT = 10;
#declare RadiusMinorSpkT = RadiusMajorSpkT - SpokeRadius;
#declare CenterSpkT = CenterOuter +
(RadiusMinorOuter +
RadiusMinorInner)/2*y;
// Now start calling the macros
// Find the outer "Roundoff" shape
#declare RoundOffType = 2;
BetweenToruses(RoundOffType,
CenterOuter, CenterSpkT,
RadiusMajorOuter, RadiusMajorSpkT,
RadiusMinorOuter, RadiusMinorSpkT,
RadiusMinorRnd,
CenterRndA, CenterRndB,
RadiusMajorRndA, RadiusMajorRndB,
Oouter, Oinner)
#declare Osm = Oinner
// Find the inner "Roundoff" shape
#declare RoundOffType = 3;
BetweenToruses(RoundOffType,
CenterInner, CenterSpkT,
RadiusMajorInner, RadiusMajorSpkT,
RadiusMinorInner, RadiusMinorSpkT,
RadiusMinorRnd,
CenterRndA, CenterRndB,
RadiusMajorRndA, RadiusMajorRndB,
Oouter, Oinner)
#declare Ism = Oinner
// Make the spoke shape
#declare Spoke =
merge {
intersection {
sphere {
CenterOuter, RadiusMinorOuter
}
object {
torus { RadiusMajorSpkT, RadiusMinorSpkT }
translate CenterSpkT
inverse
}
sphere {
CenterInner, RadiusMinorInner
inverse
}
plane { -y, 0 }
}
object { Osm }
object { Ism }
}
#declare CornerCnt = 0;
#declare GreenThing =
merge {
sphere { CenterInner, RadiusMinorInner }
#while (CornerCnt < PtsInCube)
vtilt(Spoke, Cube[CornerCnt])
#declare CornerCnt = CornerCnt + 1;
#end // while
pigment { Green/3 }
finish { Dull }
scale 2.5*v3Units
no_shadow
}
#declare CornerCnt = 0;
#declare YellowThing =
merge {
sphere { CenterInner, RadiusMinorInner }
#while (CornerCnt < PtsInCube)
vtilt(Ism, Cube[CornerCnt])
#declare CornerCnt = CornerCnt + 1;
#end // while
scale 2*v3Units
pigment { Yellow }
finish { Dull }
no_shadow
}
object { GreenThing translate < 0, 12, -40> }
object { GreenThing translate <-40, 12, 0> }
object { YellowThing translate < 37, 8, 7> }
object { YellowThing translate < 7, 8, 37> }
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Make a bump shape
#declare R1 = 20;
#declare R2 = 20;
#declare Rm = 15;
#declare dH = Pythagoras(R1 + R2, Rm);
#declare H1 = dH - R2;
#declare SinPhi = Rm/(R1 + R2);
#declare CosPhi = Pythagoras(1, SinPhi);
#declare Hc = R2*(1 - CosPhi);
#declare Lens =
merge {
intersection {
sphere { -H1*y, R1 }
plane { -y, 0 }
}
difference {
cylinder { v3Origo - nothing*y, Hc*y + nothing*y, Rm }
torus { Rm, R2 translate R2*y }
}
}
// Make the bumpy plane
difference {
merge {
object { Lens }
plane { y, 0 }
}
object { Lens rotate 180*x translate 2*Rm*vnormalize( x+z) }
object { Lens rotate 180*x translate 2*Rm*vnormalize( x-z) }
object { Lens rotate 180*x translate 2*Rm*vnormalize(-x+z) }
object { Lens rotate 180*x translate 2*Rm*vnormalize(-x-z) }
scale 0.9
texture { Soft_Silver }
no_shadow
}
// Make the crossing bars
#declare cr = 1; // cylinder radius
#declare Width = 10000;
#declare dCnt = Width/300;
#declare Cnt = -Width/2;
merge {
#while (Cnt <= Width/2)
cylinder {
<Cnt, 0, -Width/2>,
<Cnt, 0, Width/2>,
cr
}
cylinder {
<-Width/2, 0, Cnt>,
< Width/2, 0, Cnt>,
cr
}
#declare Cnt = Cnt + dCnt;
#end
pigment { color Red }
translate 55*y
}
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Make the sky
sky_sphere {
pigment {
gradient y
color_map {
[0.0 color blue 0.7]
[1.0 color rgb 1]
}
}
}
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Snap!
light_source { <1000, -300, 1000>, White*1.3 }
#declare LPos = <50, 30, 50>;
light_source { LPos, White*2 }
disc { LPos - y/100, y, 2, 0 pigment { color White } }
camera {
location 47*v3Units
look_at v3Origo - 3*y
}
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
Post a reply to this message
|
|