0 || AngleF <> 0 || ScaleF <> 1 || InvertF
const Complex ApplyMapG = ShiftG <> 0 || AngleG <> 0 || ScaleG <> 1 || InvertG
if (ApplyMapF) {
Mobius.Translate(MapF, ShiftF)
Mobius.Rotate(MapF, DegreeToRadian(AngleF))
Mobius.Scale(MapF, ScaleF)
if (InvertF) {
Mobius.ApplyInversion(MapF)
}
}
if (ApplyMapG) {
Mobius.Translate(MapG, ShiftG)
Mobius.Rotate(MapG, DegreeToRadian(AngleG))
Mobius.Scale(MapG, ScaleG)
if (InvertG) {
Mobius.ApplyInversion(MapG)
}
}
transform:
if (ApplyMapF) {
z = Mobius.TransformPoint(MapF, F(Mobius.InverseTransformPoint(MapF, z)))
} else {
z = F(z)
}
if (ApplyMapG) {
z = Mobius.TransformPoint(MapG, G(Mobius.InverseTransformPoint(MapG, z)))
} else {
z = G(z)
}
z *= Scale
properties:
#include ComplexFunctions
divider {
caption = "General"
}
option Scale {
type = Float
caption = "Scale"
details = "Scale factor applied to composite value"
default = 1
}
divider {
caption = "F(z)"
}
option F {
type = ComplexFunctions
caption = "F(z)"
default = Pow2
}
divider {
caption = "Conjugating map applied to F(z)"
}
option ShiftF {
type = Complex
caption = "Shift"
details = "Translation component"
default = 0
}
option ScaleF {
type = Float
caption = "Scale"
details = "Scale factor"
default = 1
}
option AngleF {
type = Float
caption = "Angle"
details = "Angle of rotation"
default = 0
range = [-360,360]
}
option InvertF {
type = Boolean
caption = "Invert"
details = "Apply complex inversion"
default = False
}
divider {
caption = "G(z)"
}
option G {
type = ComplexFunctions
caption = "G(z)"
default = Ident
}
divider {
caption = "Conjugating map applied to G(z)"
}
option ShiftG {
type = Complex
caption = "Shift"
details = "Translation component"
default = 0
}
option ScaleG {
type = Float
caption = "Scale"
details = "Scale factor"
default = 1
}
option AngleG {
type = Float
caption = "Angle"
details = "Angle of rotation"
default = 0
range = [-360,360]
}
option InvertG {
type = Boolean
caption = "Invert"
details = "Apply complex inversion"
default = False
}
]]>
0 || AngleF <> 0 || ScaleF <> 1 || InvertF
const Complex ApplyMapG = ShiftG <> 0 || AngleG <> 0 || ScaleG <> 1 || InvertG
if (ApplyMapF) {
Mobius.Translate(MapF, ShiftF)
Mobius.Rotate(MapF, DegreeToRadian(AngleF))
Mobius.Scale(MapF, ScaleF)
if (InvertF) {
Mobius.ApplyInversion(MapF)
}
}
if (ApplyMapG) {
Mobius.Translate(MapG, ShiftG)
Mobius.Rotate(MapG, DegreeToRadian(AngleG))
Mobius.Scale(MapG, ScaleG)
if (InvertG) {
Mobius.ApplyInversion(MapG)
}
}
transform:
if (ApplyMapF) {
z = Mobius.TransformPoint(MapF, F(Mobius.InverseTransformPoint(MapF, z)))
} else {
z = F(z)
}
if (ApplyMapG) {
z = Mobius.TransformPoint(MapG, G(Mobius.InverseTransformPoint(MapG, z)))
} else {
z = G(z)
}
z *= Scale
properties:
#include ComplexFunctions
divider {
caption = "General"
}
option Scale {
type = Float
caption = "Scale"
details = "Scale factor applied to composite value"
default = 1
}
divider {
caption = "F(z)"
}
option F {
type = ComplexFunctions
caption = "F(z)"
default = Pow2
}
divider {
caption = "Conjugating map applied to F(z)"
}
option ShiftF {
type = Complex
caption = "Shift"
details = "Translation component"
default = 0
}
option ScaleF {
type = Float
caption = "Scale"
details = "Scale factor"
default = 1
}
option AngleF {
type = Float
caption = "Angle"
details = "Angle of rotation"
default = 0
range = [-360,360]
}
option InvertF {
type = Boolean
caption = "Invert"
details = "Apply complex inversion"
default = False
}
divider {
caption = "G(z)"
}
option G {
type = ComplexFunctions
caption = "G(z)"
default = Ident
}
divider {
caption = "Conjugating map applied to G(z)"
}
option ShiftG {
type = Complex
caption = "Shift"
details = "Translation component"
default = 0
}
option ScaleG {
type = Float
caption = "Scale"
details = "Scale factor"
default = 1
}
option AngleG {
type = Float
caption = "Angle"
details = "Angle of rotation"
default = 0
range = [-360,360]
}
option InvertG {
type = Boolean
caption = "Invert"
details = "Apply complex inversion"
default = False
}
]]>
Gradient.Count()) {
Count = Gradient.Count()
}
color:
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Compute z based on PatternMap.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
switch (PatternVariationMap) {
case PatternVariationMapTypes.TrapDwell: index = Sample.TrapDwellRaw
case PatternVariationMapTypes.TrapIndex: index = Sample.TrapIndexRaw
case PatternVariationMapTypes.TrapDelta: index = Sample.TrapDeltaRaw
}
switch (PatternMap) {
case PatternMapTypes.PlanarMap
z = pixel * ViewportMagnification
z *= PlanarMapScale
z *= Cis(-DegreeToRadian(PlanarMapAngle) * IIf(VaryPlanarMapAngle, index, 1))
z += PlanarMapOffset * IIf(VaryPlanarMapOffset, index, 1)
case PatternMapTypes.SolidMap
z = Polar(Sample.TrapValue, Sample.TrapAngleRaw)
switch (SolidMapProjection) {
case ProjectionTypes.Stereographic
t = 0.5 - Sqrt(0.25-(z.r*0.5)^2)
z = PolarToComplex(z)/(1-t)
case ProjectionTypes.AzimuthalEquidistant
z.r = Asin(z.r)
z = PolarToComplex(z)
case ProjectionTypes.CircleLimit
z.r = Atanh(z.r)
z = PolarToComplex(z)
}
z *= SolidMapScale
z *= Cis(-DegreeToRadian(SolidMapAngle) * IIf(VarySolidMapAngle, index, 1))
z += SolidMapOffset * IIf(VarySolidMapOffset, index, 1)
case PatternMapTypes.CurveMap
'
' Apply AzimuthalEquidistant projection about trap center.
'
t = Sample.TrapValue
if (CurveMapBendPattern) {
t = Asin(t)
}
z = Complex( \
CurveMapAngFac * Sample.TrapAngle, \
CurveMapRadFac * t \
)
z += CurveMapOffset * IIf(VaryCurveMapOffset, index, 1)
}
'
' Set index used for selecting gradient.
'
switch (IndexMap) {
case IndexMapTypes.TrapDwell: index = Sample.TrapDwellRaw
case IndexMapTypes.TrapIndex: index = Sample.TrapIndexRaw
case IndexMapTypes.TrapDelta: index = Sample.TrapDeltaRaw
}
'
' Set depth used in noise calculation.
'
depth = IIf(IndexNoise, index, 0)
'
' Apply special case handling of CurveMap.
'
if (PatternMap = PatternMapTypes.CurveMap) {
'
' Because Perlin Noise does not produce periodic
' patterns, there will be a discontinuity at
' angle 0 unless we force it periodic in x every
' CurveMapAngFac units. We use the following:
'
' r = (N(x,y)*(w-x) + N(x-w,y)*x)/w
'
' where w = CurveMapAngFac.
'
' Note that:
' at x = 0, r = N(0,y)
' at x = w, r = N(0,y)
'
r0 = PerlinNoise.Apply3D( \
noise, \
NoiseFunction, \
NoiseOffset, \
NoiseRotation, \
NoiseFactor, \
NoiseAbs, \
z, \
depth \
)
r1 = PerlinNoise.Apply3D( \
noise, \
NoiseFunction, \
NoiseOffset, \
NoiseRotation, \
NoiseFactor, \
NoiseAbs, \
z - CurveMapAngFac, \
depth \
)
r = (r0*(CurveMapAngFac - z.x) + r1*z.x)/CurveMapAngFac
} else {
r = PerlinNoise.Apply3D( \
noise, \
NoiseFunction, \
NoiseOffset, \
NoiseRotation, \
NoiseFactor, \
NoiseAbs, \
z, \
depth \
)
}
'
' Apply Power to signed value r.
'
if (Power <> 1) {
r = IIf(r < 0, -(-r)^Power, r^Power)
}
'
' Map index to gradient index and map r to color index.
'
color = Gradient.Color(GradientOffset + WrapIndex(index, Count), Offset + Factor*r)
properties:
divider {
caption = "General Options"
}
enum IndexMapTypes {
TrapDwell, "Trap Dwell"
TrapIndex, "Trap Index"
TrapDelta, "Trap Delta"
}
option IndexMap {
type = IndexMapTypes
caption = "Index Map"
details = "Gradient index map"
default = IndexMapTypes.TrapDwell
}
option IndexNoise {
type = Boolean
caption = "Index Noise"
details = "Apply Index Map to noise pattern too"
default = True
}
option GradientOffset {
type = Integer
caption = "Gradient Offset"
details = "Offset into set of gradients"
default = 0
}
option GradientCount {
type = Integer
caption = "Gradient Count"
details = "Number of gradients to use (0 - all)"
default = 0
range = [0,]
}
option Power {
type = Float
caption = "Power"
details = "Power applied to noise"
default = 1
range = (0,)
}
option Factor {
type = Float
caption = "Factor"
details = "Factor applied to noise"
default = 0.25
}
option Offset {
type = Float
caption = "Offset"
details = "Offset added to noise"
default = 0.25
range = [-1,1]
}
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Basic PatternMap related options.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
divider {
caption = "Pattern Map"
}
enum PatternMapTypes {
PlanarMap, "Planar Map"
SolidMap, "Solid Map"
CurveMap, "Curve Map"
}
option PatternMap {
type = PatternMapTypes
caption = "Pattern Map"
details = "(Options below)"
default = PatternMapTypes.PlanarMap
size = Small
}
enum PatternVariationMapTypes {
TrapDwell, "Trap Dwell"
TrapIndex, "Trap Index"
TrapDelta, "Trap Delta"
}
option PatternVariationMap {
type = PatternVariationMapTypes
caption = "Variation Map"
details = "Used to vary angle/offset"
default = PatternVariationMapTypes.TrapDwell
size = Small
}
divider {
caption = "Planar Map - Map pattern on complex plane onto trap"
enabled = PatternMap = PatternMapTypes.PlanarMap
}
option PlanarMapScale {
type = Float
caption = "Scale Factor"
details = "Scale factor applied to pattern"
default = 1
range = (0,)
enabled = PatternMap = PatternMapTypes.PlanarMap
}
option PlanarMapAngle {
type = Float
caption = "Angle"
details = "Angle of pattern rotation"
default = 0
range = [-360,360]
enabled = PatternMap = PatternMapTypes.PlanarMap
}
option PlanarMapOffset {
type = Complex
caption = "Offset"
details = "Offset into pattern"
default = 0
enabled = PatternMap = PatternMapTypes.PlanarMap
}
option VaryPlanarMapAngle {
type = Boolean
caption = "Vary Angle"
details = "Apply Variation Map to pattern angle"
default = False
enabled = PatternMap = PatternMapTypes.PlanarMap
}
option VaryPlanarMapOffset {
type = Boolean
caption = "Vary Offset"
details = "Apply Variation Map to pattern offset"
default = False
enabled = PatternMap = PatternMapTypes.PlanarMap
}
divider {
caption = "Solid Map - Map pattern onto solid trap"
enabled = PatternMap = PatternMapTypes.SolidMap
}
enum ProjectionTypes {
Stereographic, "Stereographic"
AzimuthalEquidistant, "Azimuthal Equidistant"
CircleLimit, "Circle Limit"
}
option SolidMapProjection {
type = ProjectionTypes
caption = "Projection"
default = ProjectionTypes.Stereographic
enabled = PatternMap = PatternMapTypes.SolidMap
}
option SolidMapScale {
type = Float
caption = "Scale Factor"
details = "Scale factor applied to pattern"
default = 1
range = (0,)
enabled = PatternMap = PatternMapTypes.SolidMap
}
option SolidMapAngle {
type = Float
caption = "Angle"
details = "Angle of pattern rotation"
default = 70
range = [-360,360]
enabled = PatternMap = PatternMapTypes.SolidMap
}
option SolidMapOffset {
type = Complex
caption = "Offset"
details = "Offset into pattern"
default = 0.5+0.5i
enabled = PatternMap = PatternMapTypes.SolidMap
}
option VarySolidMapAngle {
type = Boolean
caption = "Vary Angle"
details = "Apply Variation Map to pattern angle"
default = False
enabled = PatternMap = PatternMapTypes.SolidMap
}
option VarySolidMapOffset {
type = Boolean
caption = "Vary Offset"
details = "Apply Variation Map to pattern offset"
default = False
enabled = PatternMap = PatternMapTypes.SolidMap
}
divider {
caption = "Curve Map - Map pattern onto curve trap"
enabled = PatternMap = PatternMapTypes.CurveMap
}
option CurveMapAngFac {
type = Integer
caption = "Angle Factor"
details = "Scale factor applied to angular distance (integer)"
default = 16
range = [1,]
enabled = PatternMap = PatternMapTypes.CurveMap
}
option CurveMapRadFac {
type = Float
caption = "Radial Factor"
details = "Scale factor applied to radial distance"
default = 1
range = (0,)
enabled = PatternMap = PatternMapTypes.CurveMap
}
option CurveMapOffset {
type = Complex
caption = "Offset"
details = "Offset into pattern"
default = 0
enabled = PatternMap = PatternMapTypes.CurveMap
}
option VaryCurveMapOffset {
type = Boolean
caption = "Vary Offset"
details = "Apply Variation Map to pattern offset"
default = False
enabled = PatternMap = PatternMapTypes.CurveMap
}
option CurveMapBendPattern {
type = Boolean
caption = "Bend Pattern"
details = "Bend pattern around curve (uncheck for 3D style Edged)"
default = True
enabled = PatternMap = PatternMapTypes.CurveMap
}
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The following options are useful with the PerlinNoise
' constructor and the PerlinNoise.Apply[3D] functions.
' i.e.,
'
' PerlinNoise noise = PerlinNoise(
' Amplitude0,
' Frequency0,
' AmplitudeFactor,
' FrequencyFactor,
' Octaves
' )
'
' Complex PerlinNoise.Apply(
' noise,
' NoiseFunction,
' NoiseOffset,
' NoiseRotation,
' NoiseFactor,
' NoiseAbs,
' z
' )
'
' Complex PerlinNoise.Apply3D(
' noise,
' NoiseFunction,
' NoiseOffset,
' NoiseRotation,
' NoiseFactor,
' NoiseAbs,
' z,
' depth
' )
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
#include NoiseFunctions
divider {
caption = "Noise Options"
}
option NoiseFunction {
type = NoiseFunctions
caption = "Noise"
default = NoiseFunctions.F0
size = Large
}
option NoiseFactor {
type = Float
caption = "Factor"
details = "Factor as given in the above equation"
default = 1
enabled = NoiseFunction <> NoiseFunctions.F0
}
option NoiseOffset {
type = Complex
caption = "Offset"
details = "Offset into noise"
default = 0
}
option NoiseAngle {
type = Float
caption = "Angle"
details = "Angle of pattern rotation"
default = 0
range = [-360,360]
}
option NoiseAbs {
type = Boolean
caption = "Abs"
details = "Sum the absolute value of noise"
default = False
}
constants {
NoiseRotation = Cis(DegreeToRadian(NoiseAngle))
}
divider {
caption = "Noise Iteration Options"
}
option Amplitude0 {
type = Float
caption = "Amplitude0"
details = "Amplitude used for the 1st iteration"
default = 1
range = (0,)
}
option Frequency0 {
type = Float
caption = "Frequency0"
details = "Frequency used for the 1st iteration"
default = 1
range = (0,)
}
option AmplitudeFactor {
type = Float
caption = "Amplitude Factor"
details = "Factor applied to amplitude on each iteration"
default = 0.5
range = (0,1)
}
option FrequencyFactor {
type = Float
caption = "Frequency Factor"
details = "Factor applied to frequency on each iteration"
default = 2
range = (1,)
}
option Octaves {
type = IntegerEnum(1,8)
caption = "Octaves"
details = "Number of iterations"
default = 6
}
]]>