dmj5 Class DMJ_ClipShapeRectangle

Object common:Generic common:Transform common:ClipShape dmj5:DMJ_ClipShapeRectangle

class
ClipShape:DMJ_ClipShapeRectangle

Rectangle clipping shape.

Ultra Fractal Source
class DMJ_ClipShapeRectangle(common.ulb:ClipShape) {
; Rectangle clipping shape.

public:
import "common.ulb"

func DMJ_ClipShapeRectangle(Generic pparent)
ClipShape.ClipShape(pparent)
endfunc

complex func Iterate(complex pz)
complex c              ; computed center of rectangle
complex p = pz            ; working point (generally, pixel/z)
complex q              ; working point
complex r = (1,0)          ; rotation vector
complex s              ; working point
complex t              ; working point
complex n              ; normal vector
float a = m_Aspect

if (@p_recttype == 0)        ; three corners
c = (@p_rectupperleft + @p_rectlowerright) * 0.5
p = real(p-c)*a + flip(imag(p-c)) + c                  ; correct for aspect distortion, centered on c
q = real(@p_rectupperleft-c)*a + flip(imag(@p_rectupperleft-c)) + c    ; correct for aspect distortion, centered on c
t = real(@p_rectupperright-c)*a + flip(imag(@p_rectupperright-c)) + c  ; correct for aspect distortion, centered on c
p = (p - c) * conj(r) + c    ; apply rotation
d = cabs(q - c)
s = c + (t-c)*d/cabs(t-c)    ; corrected upper-right
n = (s-q) / cabs(s-q)      ; unit vector along the top edge
s = (s-c)*conj(n)
p = (p-c)*conj(n)
s = abs(s)
if (real(p) >= -real(s) && real(p) <= real(s) && imag(p) >= -imag(s) && imag(p) <= imag(s))
m_Solid = true
endif

elseif (@p_recttype == 1)      ; center and two edges
c = @p_rectcenter
p = real(p-c)*a + flip(imag(p-c)) + c            ; correct for aspect distortion, centered on c
q = real(@p_recttop-c)*a + flip(imag(@p_recttop-c)) + c    ; correct for aspect distortion, centered on c
t = real(@p_rectright-c)*a + flip(imag(@p_rectright-c)) + c  ; correct for aspect distortion, centered on c
p = (p - c) * conj(r) + c    ; apply rotation
n = (q-c) / cabs(q-c)      ; unit vector to top edge
n = conj(flip(n))
s = real((t-c)*conj(n)) + flip(imag((q-c)*conj(n)))
p = (p-c)*conj(n)
s = abs(s)
if (real(p) >= -real(s) && real(p) <= real(s) && imag(p) >= -imag(s) && imag(p) <= imag(s))
m_Solid = true
endif

elseif (@p_recttype == 2)      ; fixed angle (edges)
c = @p_rectcenter
p = real(p-c)*a + flip(imag(p-c)) + c            ; correct for aspect distortion, centered on c
q = real(@p_recttop-c)*a + flip(imag(@p_recttop-c)) + c    ; correct for aspect distortion, centered on c
t = real(@p_rectright-c)*a + flip(imag(@p_rectright-c)) + c  ; correct for aspect distortion, centered on c
p = (p - c) * conj(r) + c    ; apply rotation
n = (0,1)^(@p_rectangle/90)    ; unit vector along top edge
s = real((t-c)*conj(n)) + flip(imag((q-c)*conj(n)))
p = (p-c)*conj(n)
s = abs(s)
if (real(p) >= -real(s) && real(p) <= real(s) && imag(p) >= -imag(s) && imag(p) <= imag(s))
m_Solid = true
endif
endif

return pz
endfunc

func SetHandles(Handles phandles)
ClipShape.SetHandles(phandles)

if (@p_recttype == 0)
m_Handles.SetHandleCount(3,0,0,0)
m_Handles.SetHandlePoint(-1,1,1,0,@p_rectupperleft,0)
m_Handles.SetHandlePoint(-1,1,2,0,@p_rectupperright,0)
m_Handles.SetHandlePoint(-1,1,3,0,@p_rectlowerright,0)

elseif (@p_recttype == 1)
m_Handles.SetHandleCount(3,0,0,0)
m_Handles.SetHandlePoint(-1,1,-30,0,@p_recttop,0)
m_Handles.SetHandlePoint(-1,3,-13,0,@p_rectcenter,0)
m_Handles.SetHandlePoint(-1,1,-28,0,@p_rectright,0)

elseif (@p_recttype == 2)
m_Handles.SetHandleCount(3,0,0,0)
m_Handles.SetHandlePoint(-1,1,-30,0,@p_recttop,0)
m_Handles.SetHandlePoint(-1,3,-13,0,@p_rectcenter,0)
m_Handles.SetHandlePoint(-1,1,-28,0,@p_rectright,0)

endif
endfunc

default:
title = "Rectangle"

int param v_dmj_clipshaperectangle
caption = "Version (DMJ_ClipShapeRectangle)"
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_clipshaperectangle < 100
endparam

int param p_recttype
caption = "Define Rect By"
default = 2
enum = "three corners" "center and two edges" "fixed angle (edges)" ;"fixed angle (corners)"
hint = "Choose how you want to define where the rectangle is. Different methods are useful in different circumstances."
endparam
complex param p_rectupperleft
caption = "Rect Upper Left"
default = #center + (-1/#magn + flip(1/#magn)) * ((0,1)^(#angle*2/#pi))
visible = (@p_recttype == 0 || @p_recttype == 3)
hint = "Selects the upper left corner of the rectangle."
endparam
complex param p_rectlowerright
caption = "Rect Lower Right"
default = #center + (1/#magn + flip(-1/#magn)) * ((0,1)^(#angle*2/#pi))
visible = (@p_recttype == 0 || @p_recttype == 3)
hint = "Selects the lower right corner of the rectangle."
endparam
complex param p_rectupperright
caption = "Rect Upper Right"
default = #center + (1/#magn + flip(1/#magn)) * ((0,1)^(#angle*2/#pi))
visible = (@p_recttype == 0)
hint = "Selects one of the other corners of the rectangle (upper right is suggested, but not required). Note that only points that are on a circle, centered on the rectangle's center, and passing through the upper left and lower right corners, will produce a valid rectangle; whatever point you actually choose for this third corner will be moved to that circle in order to produce a proper rectangle. Practically speaking, you should use this corner to set the overall angle of the rectangle, after selecting opposite corners."
endparam
float param p_rectangle
caption = "Rectangle Angle"
default = #angle*180/#pi
visible = (@p_recttype == 2 || @p_recttype == 3)
hint = "Selects the rotation angle of the rectangle. This is a bit different from the general 'Rotation' parameter. If 'Rotation' is zero, then this parameter is used to set the angle of the rectangle, and the point you select for 'Rect Top Edge' will lie exactly on the rectangle's top edge, even if it's not the center of that edge. Changing this parameter after you've selected rectangle edge points will change the size of the rectangle, as different parts of the edges have to pass through the points to make your rectangle. If you want to rotate the clipping shape without changing the size, use the general 'Rotation' parameter. Doing so, however, will affect your selection of 'Rect Edge' with the eyedropper or explorer tools. Angles are in degrees, counter-clockwise."
endparam
complex param p_rectcenter
caption = "Rect Center"
default = #center
visible = (@p_recttype == 1 || @p_recttype == 2)
hint = "Selects the center point of the rectangle."
endparam
complex param p_recttop
caption = "Rect Top Edge"
default = #center + (flip(1/#magn)) * ((0,1)^(#angle*2/#pi))
visible = (@p_recttype == 1 || @p_recttype == 2)
hint = "Selects the center of the top edge of the rectangle, for 'center and two edges', or any point on the top edge, for 'fixed angle'. Note that, for 'center and two edges', this point also sets an implicit rotation for the rectangle."
endparam
complex param p_rectright
caption = "Rect Right Edge"
default = #center + (-1/#magn) * ((0,1)^(#angle*2/#pi))
visible = (@p_recttype == 1 || @p_recttype == 2)
hint = "Selects the right edge of the rectangle. It can be anywhere on the right edge of the rectangle."
endparam

}

Constructor Summary
DMJ_ClipShapeRectangle()

DMJ_ClipShapeRectangle(Generic pparent)

Method Summary
complex Iterate(complex pz)
Transform a single point within a sequence
void SetHandles(Handles phandles)

Methods inherited from class common:ClipShape
SetAspect

Methods inherited from class common:Transform
Init, IsSolid, IterateSilent

Methods inherited from class common:Generic
GetParent

Methods inherited from class Object

Constructor Detail

DMJ_ClipShapeRectangle

public DMJ_ClipShapeRectangle(Generic pparent)

DMJ_ClipShapeRectangle

public DMJ_ClipShapeRectangle()
Method Detail

Iterate

public complex Iterate(complex pz)
Description copied from class: Transform
Transform a single point within a sequence

After a sequence has been set up with Init(), this function will be called once for each value in the sequence. Note that all values in the sequence must be processed in order (they cannot be processed out of order). If the sequence contains only one value, Init() will still be called and then Iterate() will be called just once.

Overrides:
Iterate in class Transform
Parameters:
pz - the complex value to be transformed
Returns:
the transformed value

SetHandles

public void SetHandles(Handles phandles)
Overrides:
SetHandles in class ClipShape