dmj5
Class DMJ_ClipShapeCircle

Object
  extended by common:Generic
      extended by common:Transform
          extended by common:ClipShape
              extended by dmj5:DMJ_ClipShapeCircle

class 
ClipShape:DMJ_ClipShapeCircle

Circular clipping shape.


Ultra Fractal Source

Toggle UF Source Code Display

 class DMJ_ClipShapeCircle(common.ulb:ClipShape) {
   ; Circular clipping shape.
   
 public:
   import "common.ulb"
   
   func DMJ_ClipShapeCircle(Generic pparent)
     ClipShape.ClipShape(pparent)
 
     complex c              ; computed center of circle
     complex s              ; working point
     float d = 0.0
     float a = m_Aspect
 
     if (@p_circletype == 0)    ; bounding box method
       c = (@p_circleupperleft + @p_circlelowerright) * 0.5
       if (abs(real(@p_circleupperleft)-real(@p_circlelowerright)) > abs(imag(@p_circleupperleft)-imag(@p_circlelowerright)))
         d = sqr(abs(imag(@p_circleupperleft)-imag(@p_circlelowerright)) * 0.5)
       else
         d = sqr(abs(real(@p_circleupperleft)-real(@p_circlelowerright)) * 0.5)
       endif
       s = c + sqrt(d)
 
     elseif (@p_circletype == 1)  ; center and edge method
       c = @p_circlecenter
       s = @p_circleedge
       s = real(s-c)*a + flip(imag(s-c)) + c  ; correct for aspect distortion, centered on c
       d = |s - c|
 
     elseif (@p_circletype == 2)  ; opposite edges method
       c = (@p_circleedge1 + @p_circleedge2) * 0.5
       s = @p_circleedge1
       s = real(s-c)*a + flip(imag(s-c)) + c  ; correct for aspect distortion, centered on c
       d = |s - c|
 
     elseif (@p_circletype == 3)  ; three edge points method
       ; from mathworld.wolfram.com
       float ca = real(@p_circleedge1)*(imag(@p_circleedge2)*1-imag(@p_circleedge3)*1) - \
              imag(@p_circleedge1)*(real(@p_circleedge2)*1-real(@p_circleedge3)*1) + \
              1*(real(@p_circleedge2)*imag(@p_circleedge3)-real(@p_circleedge3)*imag(@p_circleedge2))
       float cd = -( (|@p_circleedge1|)*(imag(@p_circleedge2)*1-imag(@p_circleedge3)*1) - \
              imag(@p_circleedge1)*((|@p_circleedge2|)*1-(|@p_circleedge3|)*1) + \
              1*((|@p_circleedge2|)*imag(@p_circleedge3)-(|@p_circleedge3|)*imag(@p_circleedge2)) )
       float ce = (|@p_circleedge1|)*(real(@p_circleedge2)*1-real(@p_circleedge3)*1) - \
              real(@p_circleedge1)*((|@p_circleedge2|)*1-(|@p_circleedge3|)*1) + \
              1*((|@p_circleedge2|)*real(@p_circleedge3)-(|@p_circleedge3|)*real(@p_circleedge2))
       float cf = -( (|@p_circleedge1|)*(real(@p_circleedge2)*imag(@p_circleedge3)-real(@p_circleedge3)*imag(@p_circleedge2)) - \
              real(@p_circleedge1)*((|@p_circleedge2|)*imag(@p_circleedge3)-(|@p_circleedge3|)*imag(@p_circleedge2)) + \
              imag(@p_circleedge1)*((|@p_circleedge2|)*real(@p_circleedge3)-(|@p_circleedge3|)*real(@p_circleedge2)) )
       c = -cd / (2*ca) + flip( -ce / (2*ca) )
       d = (sqr(cd)+sqr(ce)) / (4*sqr(ca)) - cf/ca
       s = c + sqrt(d)
     endif
 
     ; save results of circle definition
     m_Center = c
     m_Edge = s
     m_Radius = sqrt(d)
     m_RadiusSquared = sqr(m_Radius + @p_expansion)
   endfunc
 
   complex func Iterate(complex pz)
     complex c = m_Center        ; computed center of circle
     complex p = pz            ; working point (generally, pixel/z)
     complex s = m_Edge          ; computed edge point of the circle
     float d = m_RadiusSquared      ; computed radius squared, including expansion
     float a = m_Aspect
 
     p = real(p-c)*a + flip(imag(p-c)) + c  ; correct for aspect distortion, centered on c
     if (|c-p| <= d)
       m_Solid = true
     endif
 
     return pz
   endfunc
 
   func SetHandles(Handles phandles)
     ClipShape.SetHandles(phandles)
 
     int handletype = 1          ; assume we're using square handles
     float allowrotation = 0.0      ; assume we're zeroing out rotations
     if (@p_expansion != 0)        ; we've expanded the edge
       handletype = 6          ; use double-arrow handles for edge points
       allowrotation = 1.0        ; allow the handles to rotate
     endif
     
     if (@p_circletype == 0)
       m_Handles.SetHandleCount(3,4,0,0)
       m_Handles.SetHandlePoint(-1,3,-22028,0,m_Center,0)
       m_Handles.SetHandlePoint(-1,1,-1262,0,@p_circleupperleft,0)
       m_Handles.SetHandlePoint(-1,1,-908,0,@p_circlelowerright,0)
       complex ur = real(@p_circlelowerright) + flip(imag(@p_circleupperleft))
       complex ll = real(@p_circleupperleft) + flip(imag(@p_circlelowerright))
       m_Handles.SetHandleLine(-1,2,false,@p_circleupperleft,ur)
       m_Handles.SetHandleLine(-1,2,true,ur,@p_circlelowerright)
       m_Handles.SetHandleLine(-1,2,true,@p_circlelowerright,ll)
       m_Handles.SetHandleLine(-1,2,true,ll,@p_circleupperleft)
 
     elseif (@p_circletype == 1)
       m_Handles.SetHandleCount(2,0,0,0)
       m_Handles.SetHandlePoint(-1,3,-22028,0,m_Center,0)
       m_Handles.SetHandlePoint(-1,handletype,-983095,0,@p_circleedge,allowrotation*atan2(@p_circleedge-@p_circlecenter)*180/#pi)
 
     elseif (@p_circletype == 2)
       m_Handles.SetHandleCount(3,0,0,0)
       m_Handles.SetHandlePoint(-1,3,-22028,0,m_Center,0)
       m_Handles.SetHandlePoint(-1,handletype,1,0,@p_circleedge1,allowrotation*atan2(@p_circleedge1-m_Center)*180/#pi)
       m_Handles.SetHandlePoint(-1,handletype,2,0,@p_circleedge2,allowrotation*atan2(@p_circleedge2-m_Center)*180/#pi)
 
     elseif (@p_circletype == 3)
       m_Handles.SetHandleCount(4,0,0,0)
       m_Handles.SetHandlePoint(-1,3,-22028,0,m_Center,0)
       m_Handles.SetHandlePoint(-1,handletype,1,0,@p_circleedge1,allowrotation*atan2(@p_circleedge1-m_Center)*180/#pi)
       m_Handles.SetHandlePoint(-1,handletype,2,0,@p_circleedge2,allowrotation*atan2(@p_circleedge2-m_Center)*180/#pi)
       m_Handles.SetHandlePoint(-1,handletype,3,0,@p_circleedge3,allowrotation*atan2(@p_circleedge3-m_Center)*180/#pi)
 
     endif
 
     if (@p_expansion != 0)
       m_Handles.SetHandleCount(-1,-1,1,-1)
       m_Handles.SetHandleCircle(-1,3,m_Center,m_Radius)
     endif
   endfunc
 
 protected:
   complex m_Center
   complex m_Edge
   float m_Radius
   float m_RadiusSquared
 
 default:
   title = "Circle"
   
   int param v_dmj_clipshapecircle
     caption = "Version (DMJ_ClipShapeCircle)"
     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_clipshapecircle < 100
   endparam
 
   float param p_expansion
     caption = "Expansion"
     default = 0.0
     hint = "Sets the amount the shape will be expanded. Positive values will increase the size of the shape, negative values will decrease the size of the shape."
   endparam
   int param p_circletype
     caption = "Define Circle By"
     default = 2
     enum = "bounding box" "center and edge" "opposite edges" "three edge points"
     hint = "Choose how you want to define where the circle is. Different methods are useful in different circumstances."
   endparam
   complex param p_circleupperleft
     caption = "Box Upper Left"
     default = #center - 1/#magn + flip(1/#magn)
     visible = (@p_circletype == 0)
     hint = "Sets the upper left corner of the bounding box that the circle fits in. Note that if your image is rotated, and you're not using screen-relative clipping, the bounding box for your circle will be rotated along with the image. In that case, you may find 'center and edge' easier to use."
   endparam
   complex param p_circlelowerright
     caption = "Box Lower Right"
     default = #center + 1/#magn - flip(1/#magn)
     visible = (@p_circletype == 0)
     hint = "Sets the upper left corner of the bounding box that the circle fits in. Note that if your image is rotated, and you're not using screen-relative clipping, the bounding box for your circle will be rotated along with the image. In that case, you may find 'center and edge' easier to use."
   endparam
   complex param p_circlecenter
     caption = "Circle Center"
     default = #center
     visible = (@p_circletype == 1)
     hint = "Sets the center of the circle. If you're not sure exactly where the center should go, you may find 'opposite edges' easier to use."
   endparam
   complex param p_circleedge
     caption = "Circle Edge"
     default = #center + 1/#magn
     visible = (@p_circletype == 1)
     hint = "Sets the edge of the circle. If you need the edge to line up with something else in the image, you may find 'bounding box' easier to use."
   endparam
   complex param p_circleedge1
     caption = "Circle Edge 1"
     default = #center - 1/#magn
     visible = (@p_circletype == 2 || @p_circletype == 3)
     hint = "Sets one of the edge points of the circle."
   endparam
   complex param p_circleedge2
     caption = "Circle Edge 2"
     default = #center + 1/#magn
     visible = (@p_circletype == 2 || @p_circletype == 3)
     hint = "Sets one of the edge points of the circle."
   endparam
   complex param p_circleedge3
     caption = "Circle Edge 3"
     default = #center + flip(1/#magn)
     visible = (@p_circletype == 3)
     hint = "Sets one of the edge points of the circle."
   endparam
 
 }
 


Constructor Summary
DMJ_ClipShapeCircle()
           
DMJ_ClipShapeCircle(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_ClipShapeCircle

public DMJ_ClipShapeCircle(Generic pparent)

DMJ_ClipShapeCircle

public DMJ_ClipShapeCircle()
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