class DMJ_Inversion(common.ulb:UserTransform) {
; General Inversion transformation.
; (Ported from dmj.uxf:dmj-Inversion)
public:
import "common.ulb"
func DMJ_Inversion(Generic pparent)
UserTransform.UserTransform(pparent)
endfunc
complex func Iterate(complex pz)
m_Iterations = m_Iterations + 1
complex c = @p_invcenter ; assume inversion center is fixed
complex r = (0,1) ^ (@p_angle / 90.0) ; rotation vector
complex z = (pz-c) * r ; apply translation and rotation
z = real(z) + flip(imag(z) * @p_aspect) ; apply aspect
float d = 1.0
if (@p_invtype == 4) ; one axis only inversion
if (@p_invpower == (-1,0)) ; standard power
z = real(z) + @p_invscale*flip(1/imag(z)) ; invert just the one axis
else ; general power
z = real(z) + @p_invscale*flip(imag(z)^@p_invpower) ; do inversion
endif
else ; any other inversion type
; if (@p_invtype == 0) ; ellipse
; ; same distance everywhere
if (@p_invtype == 1) ; hypercross
d = sqrt(abs(real(z)*imag(z))/|z|) ; Kerry's simplification
elseif (@p_invtype == 2) ; flower
d = atan2(z) ; angle to z
d = abs(cos(d*@p_invorder)+@p_diameter) ; distance from origin to flower at angle z
elseif (@p_invtype == 3) ; lines
d = sqrt(sqr(real(z)/imag(z))+1) ; distance from origin to horizontal line through z
endif
if (@p_invpower == (-1,0)) ; standard power
z = @p_invscale*z*d / |z| ; do inversion (Kerry-optimized)
else ; general power
z = @p_invscale*z*d * cabs(z)^(@p_invpower-1) ; do inversion
endif
endif
z = real(z) + flip(imag(z) / @p_aspect) ; undo aspect
pz = z * conj(r) + c ; undo rotation and translation
return pz
endfunc
protected:
default:
title = "General Inversion"
int param v_dmj_inversion
caption = "Version (DMJ_Inversion)"
default = 100
hint = "This version parameter is used to detect when a change has been made to the formula that is incompatible with the previous version. When that happens, this field will reflect the old version number to alert you to the fact that an alternate rendering is being used."
visible = @v_dmj_inversion < 100
endparam
int param p_invtype
caption = "Inversion Curve"
default = 0
enum = "ellipse" "hypercross" "flower" "lines" "one axis"
hint = "Sets the shape of the curve through which inversion is done."
endparam
float param p_invscale
caption = "Inversion Scale"
default = 1.0
hint = "Scale of the inversion. This performs a similar function to changing the magnitude of the fractal zoom."
endparam
float param p_invorder
caption = "Inversion Order"
default = 3.0
hint = "Number of leaves for the flower curve."
endparam
complex param p_invcenter
caption = "Inversion Center"
default = #center
hint = "Sets the center of the inversion."
endparam
float param p_aspect
caption = "Aspect Ratio"
default = 1.0
hint = "This is how square the inversion curve is. You can distort the curve by using a value other than 1.0."
endparam
float param p_diameter
caption = "Diameter"
default = 1.5
hint = "This is the diameter of the inversion curve. Note this only matters for the 'flower' curve type."
endparam
float param p_angle
caption = "Rotation"
default = 0.0
hint = "This is the angle, in degrees, that the inversion curve should be rotated."
endparam
complex param p_invpower
caption = "Exponent"
default = (-1,0)
hint = "Gives the inversion exponent. (-1,0) gives the classic 1/z inversion type."
endparam
}