develop.pov
anführen.
In dieser Datei werden typische Szenenvorbereitungen
(Konfiguration: Kamera, Hintergrund, Lichtquellen etc.)
getroffen,
um eine umfassende, visuelle Kontrolle während der Entwicklung eines Zauberwürfels stets zur Verfügung zu haben.
Während der Entwicklung habe ich an dieser zentralen Datei permanent Korrekturen vorgenommen,
so dass die Kamera zusammen mit den Lichtquellen quasi eine Einheit bildet.
/* Kamera & Hintergrund */
camera { location <5.0, 4.4, -7.0> look_at <-0.8, -1.1, 0.0> } // Perspektive!
background { color rgb <0.5, 0.5, 0.5> } // grau
/* Lichtquellen */
light_source { <5.0, 3.5, -2.0> color rgb <0.7, 0.7, 0.7> } // ~ rechts oben
light_source { <-2.0, 5.8, -8.0> color rgb <0.7, 0.7, 0.7> } // ~ vorne oben
light_source { <-6.0, -7.0, 8.0> color rgb <0.7, 0.7, 0.7> } // ~ hinten unten
/* Texturen */
#default {
texture {
pigment { color rgb <0.2, 0.2, 0.2> } // ~ schwarz
finish { ambient 0.88 phong 1.0 diffuse 0.9 } // ~ glänzend
}
}
#declare TA = texture { pigment { color rgb <0.2, 0.2, 0.2> } } // Atom
#declare TXP = texture { pigment { color rgb <0.0, 0.0, 0.8> } } // XP = blau
#declare TXN = texture { pigment { color rgb <0.0, 0.7, 0.0> } } // XN = grün
#declare TYP = texture { pigment { color rgb <0.7, 0.7, 0.7> } } // YP = weiß
#declare TYN = texture { pigment { color rgb <0.7, 0.7, 0.0> } } // YN = gelb
#declare TZP = texture { pigment { color rgb <0.7, 0.4, 0.0> } } // ZP = orange
#declare TZN = texture { pigment { color rgb <0.7, 0.0, 0.0> } } // ZN = rot
develop.axes.pov
(Koordinatenachsen)
und
develop.mirrors.pov
(Rundumspiegel).
Diese Dateien können wahlweise hinzu- bzw. weggenommen werden.
Hierbei achtete ich besonders auf größt mögliche Unabhängigkeit.
// Achsprototyp
#declare Axis = merge {
cylinder { <-2.5, 0.0, 0.0>, <2.0, 0.0, 0.0>, 0.05 }
cone { <2.0, 0.0, 0.0>, 0.12, <2.5, 0.0, 0.0>, 0.0 }
texture {
pigment {
checker
color rgbt <0.6, 0.6, 0.6, 0.6>,
color rgbt <0.3, 0.3, 0.3, 0.6>
}
finish { ambient 0.8 phong 0.0 }
translate 0.5
}
no_shadow
}
// Drei Koordinatenachsen
object { Axis }
object { Axis rotate +90.0 * z }
object { Axis rotate -90.0 * y }
// Lichtdurchlässiger Spezialspiegel zur Visualisierung der Würfelrückseiten
#declare Mirror = disc {
<-3.2, 0.0, 0.0>, x, 2.8
pigment { color rgb 0.4 }
finish { reflection { 1.0 } ambient 0.1 diffuse 0.2 } // spiegelnd
no_shadow // um der Lichtquelle nicht im Wege zu stehen
no_reflection // damit nicht öfter als einmal gespiegelt wird
}
// Drei Spezialspiegel
object { Mirror translate <-0.2, 0.7, -1.5> } // links
object { Mirror rotate 90.0 * y translate <0.6, 0.5, 2.1> } // rechts
object { Mirror rotate 90.0 * z translate <0.4, 0.1, -0.9> } // unten
atoms.pov
cube.pov
patterns.pov
develop
beginnen, sind für den späteren Gebrauch
— also für Ihren eigenen Animationsfilm —
nicht mehr von nöten.
:-)
atoms.pov
finden Sie alle relevanten Deklarationen und Makros für die Generierung von konsistenten Atomen.
/* Framework: POV-Ray-Zauberwürfel von Stefan K. Baur */
// ----------------------------------------------------------------------------
/* Standard-Atom */
// Atom = einzelner Baustein eines Zauberwürfels
// Generierung eines würfelartigen, im Zentrum liegenden Atoms (Normgröße = 1)
#macro CreateAtom(BorderWidth)
superellipsoid { <BorderWidth, BorderWidth> scale 0.5 }
#end
#declare Atom = CreateAtom(0.13);
// ----------------------------------------------------------------------------
/* Tags */
// Tag = einzelner Farbaufkleber eines Atoms
// Generierung einfacher schattenloser Tags von bel. Texture und Ausrichtung
#macro CreateTag(Texture, Vector)
#local Epsilon = 0.001;
intersection {
object { Atom scale 1 + Epsilon }
object { Atom scale 1 - Epsilon inverse }
object { Atom scale 0.8 translate 0.5 * Vector }
texture { Texture }
no_shadow
}
#end
// ----------------------------------------------------------------------------
/* Atome */
// Generierung verschiedener Atomtypen
// Zentrales Atom einer Würfelfläche (eine Farbe bzw. ein Tag)
#macro CreateAtom1(Texture, Tag1)
union {
object { Atom texture { Texture } }
object { Tag1 }
}
#end
// Atom einer Würfelkante (zwei Farben bzw. zwei Tags)
#macro CreateAtom2(Texture, Tag1, Tag2)
union {
object { Atom texture { Texture } }
object { Tag1 }
object { Tag2 }
}
#end
// Atom einer Würfelecke (drei Farben bzw. drei Tags)
#macro CreateAtom3(Texture, Tag1, Tag2, Tag3)
union {
object { Atom texture { Texture } }
object { Tag1 }
object { Tag2 }
object { Tag3 }
}
#end
#include "develop.pov"
#include "develop.axes.pov"
#include "develop.mirrors.pov"
#include "atoms.pov"
/* Standardatom */
Atom
develop.axes.pov
und in
develop.mirrors.pov
hinweisen, die das Standardatom umgeben.
Wären diese Dateien nicht eingebunden
(//#include ...),
wäre nur das eine zentrale Atom auf grauem Hintergrund unverändert vorhanden.
#include "develop.pov"
#include "develop.axes.pov"
#include "develop.mirrors.pov"
#include "atoms.pov"
/* Tags */
CreateTag(TXP, +x) // rechts, blau
CreateTag(TXN, -x) // links, grün
CreateTag(TYP, +y) // oben, weiß
CreateTag(TYN, -y) // unten, gelb
CreateTag(TZP, +z) // hinten, orange
CreateTag(TZN, -z) // vorne, rot
// Für einen 1x1x1-Zauberwürfel bitte Folgendes aktivieren :-)
//object { Atom texture { TA } }
develop.tags.pov
und definiert die eben gerenderten Tags wie folgt:
/* Tags */
#declare TagXP = CreateTag(TXP, +x); // rechts (blau)
#declare TagXN = CreateTag(TXN, -x); // links (grün)
#declare TagYP = CreateTag(TYP, +y); // oben (weiß)
#declare TagYN = CreateTag(TYN, -y); // unten (gelb)
#declare TagZP = CreateTag(TZP, +z); // hinten (orange)
#declare TagZN = CreateTag(TZN, -z); // vorne (rot)
#include "develop.pov"
#include "develop.axes.pov"
#include "develop.mirrors.pov"
#include "atoms.pov"
#include "develop.tags.pov"
/* 6 mittige Atome */
// Atom rechts mittig (blau)
object { CreateAtom1(TA, TagXP) translate +x }
// Atom links mittig (grün)
object { CreateAtom1(TA, TagXN) translate -x }
// Atom oben mittig (weiß)
object { CreateAtom1(TA, TagYP) translate +y }
// Atom unten mittig (gelb)
object { CreateAtom1(TA, TagYN) translate -y }
// Atom hinten mittig (orange)
object { CreateAtom1(TA, TagZP) translate +z }
// Atom vorne mittig (rot)
object { CreateAtom1(TA, TagZN) translate -z }
#include "develop.pov"
#include "develop.axes.pov"
#include "develop.mirrors.pov"
#include "atoms.pov"
#include "develop.tags.pov"
/* 12 Kantenatome */
// Atom unten rechts
object { CreateAtom2(TA, TagXP, TagYN) translate +x-y }
// Atom unten links
object { CreateAtom2(TA, TagXN, TagYN) translate -x-y }
// Atom unten hinten
object { CreateAtom2(TA, TagZP, TagYN) translate +z-y }
// Atom unten vorne
object { CreateAtom2(TA, TagZN, TagYN) translate -z-y }
// Atom oben rechts
object { CreateAtom2(TA, TagXP, TagYP) translate +x+y }
// Atom oben links
object { CreateAtom2(TA, TagXN, TagYP) translate -x+y }
// Atom oben hinten
object { CreateAtom2(TA, TagZP, TagYP) translate +z+y }
// Atom oben vorne
object { CreateAtom2(TA, TagZN, TagYP) translate -z+y }
// Atom rechts hinten
object { CreateAtom2(TA, TagXP, TagZP) translate +x+z }
// Atom rechts vorne
object { CreateAtom2(TA, TagXP, TagZN) translate +x-z }
// Atom links hinten
object { CreateAtom2(TA, TagXN, TagZP) translate -x+z }
// Atom links vorne
object { CreateAtom2(TA, TagXN, TagZN) translate -x-z }
#include "develop.pov"
#include "develop.axes.pov"
#include "develop.mirrors.pov"
#include "atoms.pov"
#include "develop.tags.pov"
/* 8 Eckatome */
// Atom hinten rechts oben
object { CreateAtom3(TA, TagXP, TagYP, TagZP) translate +x+y+z }
// Atom hinten links oben
object { CreateAtom3(TA, TagXN, TagYP, TagZP) translate -x+y+z }
// Atom hinten rechts unten
object { CreateAtom3(TA, TagXP, TagYN, TagZP) translate +x-y+z }
// Atom hinten links unten
object { CreateAtom3(TA, TagXN, TagYN, TagZP) translate -x-y+z }
// Atom vorne rechts oben
object { CreateAtom3(TA, TagXP, TagYP, TagZN) translate +x+y-z }
// Atom vorne links oben
object { CreateAtom3(TA, TagXN, TagYP, TagZN) translate -x+y-z }
// Atom vorne rechts unten
object { CreateAtom3(TA, TagXP, TagYN, TagZN) translate +x-y-z }
// Atom vorne links unten
object { CreateAtom3(TA, TagXN, TagYN, TagZN) translate -x-y-z }
develop.mirrors.pov
sind.
Der Sinn dieser Rundumspiegel wird bei der Präsentation des Zauberwürfels sicher etwas klarer.
cube.pov.
Nehmen Sie sich bitte für den folgenden Code ein wenig Zeit, da dieser das Herzstück des gesamten Frameworks ist.
/* Framework: POV-Ray-Zauberwürfel von Stefan K. Baur */
#include "atoms.pov"
// ----------------------------------------------------------------------------
/* Konfiguration */
// Konfigurationsmöglichkeit einer 3x3x3-Matrix (State), siehe "Cube_Init".
// Jeder Slot dieser Matrix bekommt ein Grafikobjekt (Atome: A???).
#macro Cube_Config(State,
A020, A120, A220,
A021, A121, A221,
A022, A122, A222,
A010, A110, A210,
A011, A111, A211,
A012, A112, A212,
A000, A100, A200,
A001, A101, A201,
A002, A102, A202)
// Oberste Ebene
#declare State[0][2][0] = object { A020 translate -x+y-z }
#declare State[1][2][0] = object { A120 translate +y-z }
#declare State[2][2][0] = object { A220 translate +x+y-z }
#declare State[0][2][1] = object { A021 translate -x+y }
#declare State[1][2][1] = object { A121 translate +y }
#declare State[2][2][1] = object { A221 translate +x+y }
#declare State[0][2][2] = object { A022 translate -x+y+z }
#declare State[1][2][2] = object { A122 translate +y+z }
#declare State[2][2][2] = object { A222 translate +x+y+z }
// Mittlere Ebene
#declare State[0][1][0] = object { A010 translate -x -z }
#declare State[1][1][0] = object { A110 translate -z }
#declare State[2][1][0] = object { A210 translate +x -z }
#declare State[0][1][1] = object { A011 translate -x }
#declare State[1][1][1] = object { A111 }
#declare State[2][1][1] = object { A211 translate +x }
#declare State[0][1][2] = object { A012 translate -x +z }
#declare State[1][1][2] = object { A112 translate +z }
#declare State[2][1][2] = object { A212 translate +x +z }
// Unterste Ebene
#declare State[0][0][0] = object { A000 translate -x-y-z }
#declare State[1][0][0] = object { A100 translate -y-z }
#declare State[2][0][0] = object { A200 translate +x-y-z }
#declare State[0][0][1] = object { A001 translate -x-y }
#declare State[1][0][1] = object { A101 translate -y }
#declare State[2][0][1] = object { A201 translate +x-y }
#declare State[0][0][2] = object { A002 translate -x-y+z }
#declare State[1][0][2] = object { A102 translate -y+z }
#declare State[2][0][2] = object { A202 translate +x-y+z }
#end
// Der Würfel wird mit 27 Standard-Atomen vorbelegt bzw. konfiguriert.
#macro Cube_Default(State)
Cube_Config(State,
Atom, Atom, Atom,
Atom, Atom, Atom,
Atom, Atom, Atom,
Atom, Atom, Atom,
Atom, Atom, Atom,
Atom, Atom, Atom,
Atom, Atom, Atom,
Atom, Atom, Atom,
Atom, Atom, Atom)
#end
// Anfangskonfiguration eines Zauberwürfels.
#macro Cube_Init(State, TexA, TexR, TexL, TexU, TexD, TexB, TexF)
// Aufkleber erzeugen
#local TagR = CreateTag(TexR, +x); // rechts
#local TagL = CreateTag(TexL, -x); // links
#local TagU = CreateTag(TexU, +y); // oben
#local TagD = CreateTag(TexD, -y); // unten
#local TagB = CreateTag(TexB, +z); // hinten
#local TagF = CreateTag(TexF, -z); // vorne
#local CenterAtom = object { Atom texture { TexA } }
// Konfiguration eines gelösten Zauberwürfels
Cube_Config(State,
// Oberste Ebene
CreateAtom3(TexA, TagL, TagU, TagF),
CreateAtom2(TexA, TagU, TagF),
CreateAtom3(TexA, TagR, TagU, TagF),
CreateAtom2(TexA, TagL, TagU ),
CreateAtom1(TexA, TagU ),
CreateAtom2(TexA, TagR, TagU ),
CreateAtom3(TexA, TagL, TagU, TagB),
CreateAtom2(TexA, TagU, TagB),
CreateAtom3(TexA, TagR, TagU, TagB),
// Mittlere Ebene
CreateAtom2(TexA, TagL, TagF),
CreateAtom1(TexA, TagF),
CreateAtom2(TexA, TagR, TagF),
CreateAtom1(TexA, TagL, ),
CenterAtom,
CreateAtom1(TexA, TagR, ),
CreateAtom2(TexA, TagL, TagB),
CreateAtom1(TexA, TagB),
CreateAtom2(TexA, TagR, TagB),
// Unterste Ebene
CreateAtom3(TexA, TagL, TagD, TagF),
CreateAtom2(TexA, TagD, TagF),
CreateAtom3(TexA, TagR, TagD, TagF),
CreateAtom2(TexA, TagL, TagD ),
CreateAtom1(TexA, TagD ),
CreateAtom2(TexA, TagR, TagD ),
CreateAtom3(TexA, TagL, TagD, TagB),
CreateAtom2(TexA, TagD, TagB),
CreateAtom3(TexA, TagR, TagD, TagB))
#end
// Ausgabe der konfigurierten 3x3x3-Matrix, Ausgabe des Zauberwürfels.
#macro Cube_Show(State)
union {
#local X = 0;
#while (X < 3)
#local Y = 0;
#while (Y < 3)
#local Z = 0;
#while (Z < 3)
object { State[X][Y][Z] }
#local Z = Z + 1;
#end
#local Y = Y + 1;
#end
#local X = X + 1;
#end
}
#end
// ----------------------------------------------------------------------------
/* Rotationen */
// x-Rotation: Eine y-z-Ebene (XIndex) wird um einen Winkel (Angle) gedreht.
#macro Cube_RotateX(State, XIndex, Angle)
#if (Angle != 0.0) // höhere Effizienz
#local X = XIndex;
#local Y = 0;
#while (Y < 3)
#local Z = 0;
#while (Z < 3)
#local State[X][Y][Z] = object {
State[X][Y][Z]
rotate x * Angle
}
#local Z = Z + 1;
#end
#local Y = Y + 1;
#end
#end
#end
// y-Rotation: Eine x-z-Ebene (YIndex) wird um einen Winkel (Angle) gedreht.
#macro Cube_RotateY(State, YIndex, Angle)
#if (Angle != 0.0) // höhere Effizienz
#local Y = YIndex;
#local X = 0;
#while (X < 3)
#local Z = 0;
#while (Z < 3)
#local State[X][Y][Z] = object {
State[X][Y][Z]
rotate y * Angle
}
#local Z = Z + 1;
#end
#local X = X + 1;
#end
#end
#end
// z-Rotation: Eine x-y-Ebene (ZIndex) wird um einen Winkel (Angle) gedreht.
#macro Cube_RotateZ(State, ZIndex, Angle)
#if (Angle != 0.0) // höhere Effizienz
#local Z = ZIndex;
#local X = 0;
#while (X < 3)
#local Y = 0;
#while (Y < 3)
#local State[X][Y][Z] = object {
State[X][Y][Z]
rotate z * Angle
}
#local Y = Y + 1;
#end
#local X = X + 1;
#end
#end
#end
// ----------------------------------------------------------------------------
/* Rotationssequenzen */
// Kernfunktion für Sequenzen, die einen Wert zwischen 0 und 1 ermittelt.
// Anwendung: Für Animationen kann man für Value die Zeit (clock) einsetzen.
// Voraussetzung: Start < End
// Resultat:
// * Falls (Value <= Start) -> 0.0
// * Falls (Value >= End) -> 1.0
// * Sonst (Start < Value < End) -> ((Value - Start) / (End - Start))
#declare interpolator = function(Start, End, Value) {
min(1.0, max(0.0, (Value - Start) / (End - Start)))
}
// Turn: Eine Ebene (?Index) wird in Abhängigkeit von Value (z. B.: clock)
// minimal um 0° (clock <= Start) und maximal um 90° (clock >= End) gedreht.
// Ist clock >= End wirkt sich die Rotation auch auf die gegebene
// 3x3x3-Matrix (State) aus.
// Der Spin {Negative = -1.0; Positive = +1.0} drückt die Drehrichtung aus.
// Konsistenz: Der Zustand des Würfels (State bzw. 3x3x3-Matrix) muss nach
// abgeschlossener 90°-Drehung (Grafik-Drehung) ebenfalls mit einer adäquaten
// Drehung (State-Drehung) angepasst werden, damit weitere Turns unabhängig
// von den vorhergehenden Turns ausgeführt werden können.
// x-Turn: Eine y-z-Ebene (XIndex) wird konsistent gedreht (Grafik & State).
#macro Cube_TurnX(State, XIndex, Spin, Start, End, Value)
#local X = XIndex;
// Grafik-Drehung
Cube_RotateX(State, X, 90.0 * Spin * interpolator(Start, End, Value))
#if (Value >= End) // Abschlussbedingung -> State-Drehung
#if (Spin > 0.0)
#local MemX00 = State[X][0][0];
#local State[X][0][0] = State[X][0][2];
#local State[X][0][2] = State[X][2][2];
#local State[X][2][2] = State[X][2][0];
#local State[X][2][0] = MemX00;
#local MemX01 = State[X][0][1];
#local State[X][0][1] = State[X][1][2];
#local State[X][1][2] = State[X][2][1];
#local State[X][2][1] = State[X][1][0];
#local State[X][1][0] = MemX01;
#else
#local MemX00 = State[X][0][0];
#local State[X][0][0] = State[X][2][0];
#local State[X][2][0] = State[X][2][2];
#local State[X][2][2] = State[X][0][2];
#local State[X][0][2] = MemX00;
#local MemX01 = State[X][0][1];
#local State[X][0][1] = State[X][1][0];
#local State[X][1][0] = State[X][2][1];
#local State[X][2][1] = State[X][1][2];
#local State[X][1][2] = MemX01;
#end
#end
#end
// y-Turn: Eine x-z-Ebene (YIndex) wird konsistent gedreht (Grafik & State).
#macro Cube_TurnY(State, YIndex, Spin, Start, End, Value)
#local Y = YIndex;
// Grafik-Drehung
Cube_RotateY(State, Y, 90.0 * Spin * interpolator(Start, End, Value))
#if (Value >= End) // Abschlussbedingung -> State-Drehung
#if (Spin > 0.0)
#local Mem0Y0 = State[0][Y][0];
#local State[0][Y][0] = State[2][Y][0];
#local State[2][Y][0] = State[2][Y][2];
#local State[2][Y][2] = State[0][Y][2];
#local State[0][Y][2] = Mem0Y0;
#local Mem1Y0 = State[1][Y][0];
#local State[1][Y][0] = State[2][Y][1];
#local State[2][Y][1] = State[1][Y][2];
#local State[1][Y][2] = State[0][Y][1];
#local State[0][Y][1] = Mem1Y0;
#else
#local Mem0Y0 = State[0][Y][0];
#local State[0][Y][0] = State[0][Y][2];
#local State[0][Y][2] = State[2][Y][2];
#local State[2][Y][2] = State[2][Y][0];
#local State[2][Y][0] = Mem0Y0;
#local Mem1Y0 = State[1][Y][0];
#local State[1][Y][0] = State[0][Y][1];
#local State[0][Y][1] = State[1][Y][2];
#local State[1][Y][2] = State[2][Y][1];
#local State[2][Y][1] = Mem1Y0;
#end
#end
#end
// z-Turn: Eine x-y-Ebene (ZIndex) wird konsistent gedreht (Grafik & State).
#macro Cube_TurnZ(State, ZIndex, Spin, Start, End, Value)
#local Z = ZIndex;
// Grafik-Drehung
Cube_RotateZ(State, Z, 90.0 * Spin * interpolator(Start, End, Value))
#if (Value >= End) // Abschlussbedingung -> State-Drehung
#if (Spin > 0.0)
#local Mem00Z = State[0][0][Z];
#local State[0][0][Z] = State[0][2][Z];
#local State[0][2][Z] = State[2][2][Z];
#local State[2][2][Z] = State[2][0][Z];
#local State[2][0][Z] = Mem00Z;
#local Mem10Z = State[1][0][Z];
#local State[1][0][Z] = State[0][1][Z];
#local State[0][1][Z] = State[1][2][Z];
#local State[1][2][Z] = State[2][1][Z];
#local State[2][1][Z] = Mem10Z;
#else
#local Mem00Z = State[0][0][Z];
#local State[0][0][Z] = State[2][0][Z];
#local State[2][0][Z] = State[2][2][Z];
#local State[2][2][Z] = State[0][2][Z];
#local State[0][2][Z] = Mem00Z;
#local Mem10Z = State[1][0][Z];
#local State[1][0][Z] = State[2][1][Z];
#local State[2][1][Z] = State[1][2][Z];
#local State[1][2][Z] = State[0][1][Z];
#local State[0][1][Z] = Mem10Z;
#end
#end
#end
// ----------------------------------------------------------------------------
/* Mnemonik & Abstraktion */
#declare Positive = +1.0;
#declare Negative = -1.0;
#declare Center = 1;
#declare Left = 0;
#declare Right = 2;
#declare Up = 2;
#declare Down = 0;
#declare Front = 0;
#declare Back = 2;
// L := Eine viertel Umdrehung der linken Ebene im Uhrzeigersinn.
#macro Cube_L (State, Start, End, Value)
Cube_TurnX(State, Left, Negative, Start, End, Value)
#end
// L_ := Eine viertel Umdrehung der linken Ebene gegen den Uhrzeigersinn.
#macro Cube_L_(State, Start, End, Value)
Cube_TurnX(State, Left, Positive, Start, End, Value)
#end
// R := Eine viertel Umdrehung der rechten Ebene im Uhrzeigersinn.
#macro Cube_R (State, Start, End, Value)
Cube_TurnX(State, Right, Positive, Start, End, Value)
#end
// R_ := Eine viertel Umdrehung der rechten Ebene gegen den Uhrzeigersinn.
#macro Cube_R_(State, Start, End, Value)
Cube_TurnX(State, Right, Negative, Start, End, Value)
#end
// U := Eine viertel Umdrehung der oberen Ebene im Uhrzeigersinn.
#macro Cube_U (State, Start, End, Value)
Cube_TurnY(State, Up, Positive, Start, End, Value)
#end
// U_ := Eine viertel Umdrehung der oberen Ebene gegen den Uhrzeigersinn.
#macro Cube_U_(State, Start, End, Value)
Cube_TurnY(State, Up, Negative, Start, End, Value)
#end
// D := Eine viertel Umdrehung der unteren Ebene im Uhrzeigersinn.
#macro Cube_D (State, Start, End, Value)
Cube_TurnY(State, Down, Negative, Start, End, Value)
#end
// D_ := Eine viertel Umdrehung der unteren Ebene gegen den Uhrzeigersinn.
#macro Cube_D_(State, Start, End, Value)
Cube_TurnY(State, Down, Positive, Start, End, Value)
#end
// F := Eine viertel Umdrehung der vorderen Ebene im Uhrzeigersinn.
#macro Cube_F (State, Start, End, Value)
Cube_TurnZ(State, Front, Negative, Start, End, Value)
#end
// F_ := Eine viertel Umdrehung der vorderen Ebene gegen den Uhrzeigersinn.
#macro Cube_F_(State, Start, End, Value)
Cube_TurnZ(State, Front, Positive, Start, End, Value)
#end
// B := Eine viertel Umdrehung der hinteren Ebene im Uhrzeigersinn.
#macro Cube_B (State, Start, End, Value)
Cube_TurnZ(State, Back, Positive, Start, End, Value)
#end
// B_ := Eine viertel Umdrehung der hinteren Ebene gegen den Uhrzeigersinn.
#macro Cube_B_(State, Start, End, Value)
Cube_TurnZ(State, Back, Negative, Start, End, Value)
#end
Cube_Default.
#include "develop.pov"
#include "develop.axes.pov"
#include "develop.mirrors.pov"
#include "cube.pov"
// Der Zustand des Zauberwürfels
#declare SolvedCube = array[3][3][3];
// Farblose Würfelkonfiguration mit Standardatomen
Cube_Default(SolvedCube)
// Ausgabe des Zauberwürfels
Cube_Show(SolvedCube)
Cube_Init.
#include "develop.pov"
#include "develop.axes.pov"
#include "develop.mirrors.pov"
#include "cube.pov"
// Der Zustand des Zauberwürfels
#declare SolvedCube = array[3][3][3];
// Anfangskonfiguration eines Zauberwürfels (Texturen aus develop.pov)
Cube_Init(SolvedCube, TA, TXP, TXN, TYP, TYN, TZP, TZN)
// Ausgabe des Zauberwürfels
Cube_Show(SolvedCube)
Cube_Config.
#include "develop.pov"
#include "develop.mirrors.pov"
#include "cube.pov"
/* Spezialatome */
#declare Null = sphere { 0.0, 0.00001 }
#declare Corner = sphere { 0.0, 0.5 }
#declare EdgeZ = superellipsoid { <1, 0.25> scale 0.5 }
#declare EdgeY = object { EdgeZ rotate 90.0 * x }
#declare EdgeX = object { EdgeZ rotate 90.0 * y }
#declare Face = CreateAtom(0.25);
/* De-Textur */
#declare DeBlack = texture { pigment { color rgb <0.18, 0.18, 0.18> } }
#declare DeRed = texture { pigment { color rgb <0.60, 0.11, 0.11> } }
#declare DeGold = texture { pigment { color rgb <0.63, 0.55, 0.18> } }
#declare DeTexture = texture {
gradient -y
texture_map {
[0.00 DeBlack]
[0.27 DeBlack]
[0.40 DeRed]
[0.61 DeRed]
[0.73 DeGold]
[1.00 DeGold]
}
translate 1.5 * y
scale 3.1 * y
}
#macro DeCube(State)
#local X = 0;
#while (X < 3)
#local Y = 0;
#while (Y < 3)
#local Z = 0;
#while (Z < 3)
#declare State[X][Y][Z] = object {
State[X][Y][Z]
texture { DeTexture }
}
#local Z = Z + 1;
#end
#local Y = Y + 1;
#end
#local X = X + 1;
#end
#end
/* De-Würfel */
#declare SpecialCube = array[3][3][3];
Cube_Config(SpecialCube,
Corner, EdgeX, Corner,
EdgeZ , Face , EdgeZ ,
Corner, EdgeX, Corner,
EdgeY , Face , EdgeY ,
Face , Null , Face ,
EdgeY , Face , EdgeY ,
Corner, EdgeX, Corner,
EdgeZ , Face , EdgeZ ,
Corner, EdgeX, Corner)
DeCube(SpecialCube)
Cube_Show(SpecialCube)
Cube_Show.
#include "develop.pov"
#include "develop.axes.pov"
#include "develop.mirrors.pov"
#include "cube.pov"
#declare MyCube = array[3][3][3];
Cube_Init(MyCube, TA, TXP, TXN, TYP, TYN, TZP, TZN)
// Sequenz für Blume
Cube_TurnX(MyCube, Left, Negative, 0.20, 0.30, clock)
Cube_TurnX(MyCube, Right, Negative, 0.25, 0.30, clock)
Cube_TurnZ(MyCube, Center, Negative, 0.40, 0.50, clock)
Cube_TurnX(MyCube, Left, Positive, 0.60, 0.70, clock)
Cube_TurnX(MyCube, Right, Positive, 0.65, 0.70, clock)
Cube_TurnY(MyCube, Up, Positive, 0.80, 0.90, clock)
Cube_TurnY(MyCube, Down, Positive, 0.85, 0.90, clock)
// Rücksequenz
Cube_TurnX(MyCube, Left, Negative, 1.20, 1.30, clock)
Cube_TurnX(MyCube, Right, Negative, 1.25, 1.30, clock)
Cube_TurnZ(MyCube, Center, Positive, 1.40, 1.50, clock)
Cube_TurnX(MyCube, Left, Positive, 1.60, 1.70, clock)
Cube_TurnX(MyCube, Right, Positive, 1.65, 1.70, clock)
Cube_TurnY(MyCube, Up, Negative, 1.80, 1.90, clock)
Cube_TurnY(MyCube, Down, Negative, 1.85, 1.90, clock)
Cube_Show(MyCube)
cube.pov
finden Sie im Folgenden in der dritten
Framework-Datei
patterns.pov
oder auf der Test- und Tutoriumseite
POV-Ray-Zauberwürfel-Tests.
develop.cube.anixyz.pov
erhält man jedoch noch keine Animationsdatei.
Sie benötigen dazu noch folgende
INI-Datei,
mit der der
POV-Ray-Renderer
89
PNG-Dateien
generiert, sowie ein Programm zum Zusammenführen dieser Dateien
(hier ImageMagick).
Input_File_Name=develop.cube.ani.xyz.pov
Output_File_Type=N
Bits_Per_Color=3
Width=200
Height=150
Antialias=On
Antialias_Threshold=0.001
Antialias_Depth=3
Jitter=Off
Initial_Frame=0
Final_Frame=88
Initial_Clock=0
Final_Clock=2
convert
von
ImageMagick
etwa wie folgt:
convert
-quality 100
-delay 12
-layers trim-bounds
-layers optimize-transparency
.\develop.cube.ani.xyz??.png
.\develop.cube.ani.xyz.gif
patterns.pov
zusammengestellt.
/* Framework: POV-Ray-Zauberwürfel von Stefan K. Baur */
#include "cube.pov"
// ----------------------------------------------------------------------------
/* Hilfsmakro */
#macro Intervals(Count, StartArray, EndArray, Start, End)
#local Delta = (End - Start) / Count;
#local I = 0;
#while (I < Count)
#local StartArray[I] = Start + I * Delta;
#local EndArray[I] = StartArray[I] + 0.75 * Delta;
#local I = I + 1;
#end
#end
// ----------------------------------------------------------------------------
/* Patterns */
// Pattern: "Pons Asinorum" ~ "Eselsbrücke" (12 Turns)
#macro Pattern_PonsAsinorum(State, Start, End, Value)
#local Count = 12;
#local SA = array[Count];
#local EA = array[Count];
Intervals(Count, SA, EA, Start, End)
Cube_F (State, SA[ 0], EA[ 0], Value)
Cube_F (State, SA[ 1], EA[ 1], Value)
Cube_B (State, SA[ 2], EA[ 2], Value)
Cube_B (State, SA[ 3], EA[ 3], Value)
Cube_R (State, SA[ 4], EA[ 4], Value)
Cube_R (State, SA[ 5], EA[ 5], Value)
Cube_L (State, SA[ 6], EA[ 6], Value)
Cube_L (State, SA[ 7], EA[ 7], Value)
Cube_U (State, SA[ 8], EA[ 8], Value)
Cube_U (State, SA[ 9], EA[ 9], Value)
Cube_D (State, SA[10], EA[10], Value)
Cube_D (State, SA[11], EA[11], Value)
#end
// Pattern: "Six Spot" ~ "Blume" (8 Turns)
#macro Pattern_SixSpot(State, Start, End, Value)
#local Count = 8;
#local SA = array[Count];
#local EA = array[Count];
Intervals(Count, SA, EA, Start, End)
Cube_U (State, SA[0], EA[0], Value)
Cube_D_(State, SA[1], EA[1], Value)
Cube_R (State, SA[2], EA[2], Value)
Cube_L_(State, SA[3], EA[3], Value)
Cube_F (State, SA[4], EA[4], Value)
Cube_B_(State, SA[5], EA[5], Value)
Cube_U (State, SA[6], EA[6], Value)
Cube_D_(State, SA[7], EA[7], Value)
#end
// Pattern: "Cube in a Cube" ~ "Würfel in Würfel" (18 Turns)
#macro Pattern_CubeInACube(State, Start, End, Value)
#local Count = 18;
#local SA = array[Count];
#local EA = array[Count];
Intervals(Count, SA, EA, Start, End)
Cube_F (State, SA[ 0], EA[ 0], Value)
Cube_L (State, SA[ 1], EA[ 1], Value)
Cube_F (State, SA[ 2], EA[ 2], Value)
Cube_U_(State, SA[ 3], EA[ 3], Value)
Cube_R (State, SA[ 4], EA[ 4], Value)
Cube_U (State, SA[ 5], EA[ 5], Value)
Cube_F (State, SA[ 6], EA[ 6], Value)
Cube_F (State, SA[ 7], EA[ 7], Value)
Cube_L (State, SA[ 8], EA[ 8], Value)
Cube_L (State, SA[ 9], EA[ 9], Value)
Cube_U_(State, SA[10], EA[10], Value)
Cube_L_(State, SA[11], EA[11], Value)
Cube_B (State, SA[12], EA[12], Value)
Cube_D_(State, SA[13], EA[13], Value)
Cube_B_(State, SA[14], EA[14], Value)
Cube_L (State, SA[15], EA[15], Value)
Cube_L (State, SA[16], EA[16], Value)
Cube_U (State, SA[17], EA[17], Value)
#end
Pattern_PonsAsinorum
finden Sie unter
Pons Asinorum.
Pattern_SixSpot
finden Sie unter
Six Spot.
Pattern_CubeInACube
(mein Lieblingspattern)
finden Sie unter
Cube in a Cube.