cxdraw←{⎕IO ⎕ML←0 1 ⍝ Complex function drawing. draw←{ ⍝ MouseMove callback. _ _ y x _ _←⍵ ⍝ mouse coords. ⍺←y x ⍝ previous coords (default here). a.onMouseMove←'draw'(y x) ⍝ starting coords for next segment. from←↑⍺(y x) ⍝ domain endpoints. _←from poly blue ⍝ blue domain line. into←range from ⍝ draw range line in segments. coords↑(y x)into ⍝ update coords in form Caption. } marks←{ ⍝ double click: mark domain & range. _ _ y x _ _←⍵ ⍝ mouse pointer coords. _←y x mark 1 blue ⍝ domain marker into←⊃↓app under zg 3 2⍴y x ⍝ maps_to (range) point. _←into mark 1 red ⍝ range marker. coords↑(y x)into ⍝ update coords in form Caption. } range←{ ⍝ draw range line in segments. dom←⍵[0;]-[1](0.01×⍳101)∘.×-⌿⍵ ⍝ 100 domain line segments. rng←app under zg dom ⍝ corresponding range points. into←,¯1 2↑rng ⍝ final points for coords fn. ~1∊(⌊rng)∊⍳101:into ⍝ no range points visible: quit. cut←100<÷⌿+/|2-/[1]↑rng dom ⍝ cut where red/blue slope > 100. ~1∊cut:into⊣rng poly red ⍝ no discontinuity: draw red line. eps←{⊖2 2↑¯1⊖⍵} ⍝ endpoints of range. 1↑cut:∇ eps 1↓dom ⍝ first point is cut: ignore it ¯1↑cut:∇ eps ¯1↓dom ⍝ last point is cut: ignore it. ⊃⌽∇∘eps¨(1,cut)⊂[0]dom ⍝ draw both halves of line. } app←⍺⍺{ ⍝ complex function application 11::zg ¯1 ¯1 ⍝ overflow: map to off-screen. 5::∇¨under(↓∘⍉)⍵ ⍝ ⍺⍺ refuses array: try each point. cx←1 0J1∘(+.×) ⍝ complex from coords cd←9 11∘(∘.○) ⍝ coords from complex 0=⎕NC'⍺':cd ⍺⍺ cx ⍵ ⍝ monadic application cd(cx ⍺)⍺⍺ cx ⍵ ⍝ dyadic application } ⍝ :: [C] → [C] plane←{ ⍝ complex plane. f←⎕NEW⊂'Form' ⍝ containing form f.(Posn Size)←(3 0)(60 45) ⍝ top(ish) left. f.Caption←⍵ ⍝ ref to new form. f.onKeyPress←'keyp' ⍝ esc to quit. coo←f.Coord ⍝ store current prop. f.Coord←'Pixel' ⍝ change prop. f.(Size←2⍴⌊/Size) ⍝ make form square. f.Coord←coo ⍝ reset prop. a←f.⎕NEW⊂'Static' ⍝ white backdrop. a.(Posn Size)←(0 0)(100 100) ⍝ occupies whole form. line←{⍺.⎕NEW'Poly'⍵} ⍝ new line. fmto←{'Points'(↓⍉↑⍵)} ⍝ points property for gui. a.re←a line⊂fmto 50,¨0 100 ⍝ real axis. a.im←a line⊂fmto 100 0,¨50 ⍝ imaginary axis. posn←'Points'(50-50÷⍺ ⍺) ⍝ bounding size←'Size'(100÷⍺ ⍺) ⍝ square of a⊣a.uc←a.⎕NEW'Ellipse'(posn size) ⍝ unit "circle". } down←{ ⍝ MouseDown: 1≡4⊃⍵:a.onMouseMove←'draw' ⍝ lft: start drawing. 2≡4⊃⍵:(a a).Visible←0 1 ⍝ rgt: clear screen. } stop←{a.onMouseMove←0} ⍝ MouseUp: stop drawing. keyp←{'EP'≡2⊃⍵:2 ⎕NQ a.##'Close'} ⍝ Esc key: quit. coords←{ ⍝ domain and range coords. nums←~∘' '¨8 2∘⍕¨⍉zg ⍵ ⍝ format of coords to 2 dec places. glue←{↑,∘(⍺∘,)/⍵} ⍝ ⍺-join vector ⍵. text←' -> 'glue↓'j'glue nums ⍝ 'fm -> to' a.##.Caption←'cxdraw ',text ⍝ display in Caption of Form. } mbrot←{ ⍝ poor man's Mandelbrot. _ _ y x _ _←⍵ ⍝ mouse pointer coords. to←,app⍣10⍨zg↑,↓y x ⍝ after 10 iterations. 2∧.≥|to:y x mark 0 ⍝ in-bounds: mark point. } zg←↑∘((⍵÷100÷2 ¯2)∘×)∘↓∘(-∘50)∘⊖∘⍉ ⍝ scale: complex from gui coords. under←{⍵⍵⍣¯1 ⍺⍺ ⍵⍵ ⍵} ⍝ aka "dual". red blue←{'FCol'(⍵↑255)}¨3 ¯3 ⍝ red and blue line colours. mark←{'a.'⎕WC'Marker'⍺,⍵} ⍝ unnamed marker object. poly←{'a.'⎕WC'Poly'⍺ ⍵} ⍝ unnamed poly object. a←⍵ plane⊃⎕SI ⍝ complex plane. ⍺←0 ⋄ _←⍺{ ⍝ regular drawing or mandelbrot? ⍺:a.onMouseMove←'mbrot' ⍝ mandelbrot: set callback. a.onMouseDown←'down' ⍝ otherwise: regular drawing. a.onMouseDblClick←'marks' ⍝ double-click to mark. 1:a.onMouseUp←'stop' ⍝ release to stop drawing. }⍵ ⎕DQ a.## ⍝ await events. } code_colours test script Back to: notes Back to: Workspaces