oh-no-graphic

Started by didi, May 25, 2009, 09:19:29 AM

Previous topic - Next topic

didi

PART1 :

my old rgb-mixer enhanced with one line for ppm-graphic-format : ; rgb_mixer_ppm.lsp  25may2009 dmemos
 
( set 'cmax 255 )
( set 'cmin 0 )
( set 'cdelta ( / ( sub cmax cmin) 10 )) ; "/" only for int else "div"
( set 'drgb ( dup cdelta 3 ))
( set 'white ( dup cmax 3 ))
( set 'black ( dup cmin 3 ))
( set 'red ( list cmax cmin cmin ))
( set 'green ( list cmin cmax cmin ))
( set 'blue ( list cmin cmin cmax ))

( define ( limit rgbx)
  ( if ( > rgbx cmax) cmax
   ( if ( < rgbx cmin) cmin rgbx )))

( define ( rgb-add rgb1 rgb2 )
( map limit ( map add rgb1 rgb2)))

( define ( rgb-sub rgb1 rgb2 )
( map limit ( map sub rgb1 rgb2)))

( define ( rgb-complement rgb1 )
( rgb-sub white rgb1 ))

( set 'yellow ( rgb-add red green ))
( set 'cyan ( rgb-add green blue ))
( set 'magenta ( rgb-add red blue ))

( define ( rgb-lighter rgb1 i )
( if ( = nil i ) (set 'i 1 ))
( rgb-add rgb1 ( map mul drgb ( list i i i ))))

( define ( rgb-darker rgb1 i )
( if ( = nil i ) (set 'i 1 ))
( rgb-sub rgb1 ( map * drgb ( list i i i ))))

( set 'darkgrey ( rgb-lighter black 3 ))
( set 'lightgrey ( rgb-darker white ))

; translate rgb list to a string for ppm-format eg. ( 75 75 75 )  ->  "KKK"
( define ( ppm mrgb )  ( join ( map char mrgb )))

didi

#1
Part2 :
; onograph7.lsp   oh-no-graphic   dmemos 25.5.2009
( change-dir "C:\arb" )
( load "rgb_mixer_ppm.lsp" )

( set 'width 50  'height 50 )
( set 'bkcolor ( ppm yellow ))
( set 'mcolor ( ppm red ))

( silent ; silent only for testphase with nl-gui
  ( set 'bmparray ( array ( * width height) (list bkcolor)))
)

; set point
( setf (bmparray 1 )  ( ppm blue )  )

; diagonal-line
( for ( i 0 49  )
   ( setf ( bmparray ( + i (* i 50 ))) mcolor ))

; output as ppm-file , colormax-value is "255"
( write-file "first.ppm"
     ( append "P6n" (string width) " " (string height) "n255n" ))
; convert bitmap to string and append to ppm-file
( append-file "first.ppm" (join (array-list bmparray )))

( println ( length bmpstr ) )

didi

#2
Crazy ! ?



This are some lines of code to generate simple ppm-graphics in newLISP . You can view the resulting ppm file  with the most graphic viewer .



Why ??



It's so much fun to program in newLISP itself . Only some lines are needed for a first result - without any complicated graphic-lib . And its fast enough.





Next ?



Make some basic drawing routines lines, shapes, fonts .

And an ppm to png converter .



Vision :

Generating simple x-y-plots or gif-graphics with newLISP and your browser.





PS:  Everyone will probably say "Oh no ! " to this solution , thats the reason for this project-name "onographic"  :-)

Lutz

#3
Look also into 'mat', 'multiply' etc. matrix operations, which might help you to speed up your code.



Not crazy at all! People have done low-level byte crunching with newLISP before and often with acceptable speed.

didi

#4
Thanks Lutz for your  help .

I don't want to bother someone here, but i makes really fun to program this from scratch in newLISP .  There is only one thing ... there will always be one way to make it smarter within newLISP.  I have to live with this ;)


; line-test3 28may2009 dmemos

( set 'plist '())

( define  ( point x y )
   ( push ( list (int x) (int y) ) plist ))

( define ( vertical_line x y1 y2 )
   ( for ( y y1 y2 ) ( point x y )))
     
( define ( horizontal_line x1 x2 y )
   ( for ( x x1 x2 ) ( point x y )))

( define (normal_line  x1 x2 y1 y2 )
   ( set 'dm (div ( sub y2 y1 ) ( sub x2 x1 )))
   ( set 'y y1 )
   ( for ( x x1 x2 )
      ( point x y )
      ( set 'y ( add y dm ))))

( define ( line  x1 y1 x2 y2 )
     ( if ( = x1 x2 )
          ( if ( = y1 y2 )
                ( point x1 y1 )
                ( vertical_line x1 y1 y2 ))
          ( if ( = y1 y2 )
                ( horizontal_line x1 x2 y1 )
                ( normal_line x1 y1 x2 y2 ))))

; test          
( line 30 40 100 110 )

( unique plist )  ; delete double entries
( println plist )  


Hope comming back with a ready to use version .

cormullion

#5
This is a clever idea! Can't get it working yet, though...



I'm not seeing anything other than a black square when I run your code and open the graphic in GraphicConverter (a multi-purpose MacOS file converter). The file first.ppm doesn't seem to have any content other than the header. Is there something tricky about UTF-8, or append-file, or newLISP-on-Mac that's not working...???

didi

#6
Here you can download the generated file, as it is generated on my pc:

http://www.dmemos.de/onographic/first.ppm">//http://www.dmemos.de/onographic/first.ppm



Here is a 400% zoomed screendump how it is shown in photoimpact:



http://www.dmemos.de/onographic/first.png">





Cormullion, do you have the "rgb_mixer_ppm.lsp" in the same directory ?



PS: I have copied the code from here back to my newLISP-GS and it is still working.

cormullion

#7
I put all the code into the same file. I think it's correct. I'm still of the opinion that the Unicode is a problem, since my bmparray is filling up like this:



("19519119519100" "19519119519100" "19519119519100" "19519119519100" ...



I may look at 'pack' tomorrow to see if that provides a solution. But now, bed... :)

didi

#8
I think you are right. The bitmap-array should look like this :



 .... "25525500" "25525500" "25525500" "2550000")

didi

#9
http://www.dmemos.de/onographic/onograph11/first-1-june-09.png">



This 200x200 pixels needed 0.156s, if i increase the canvas to 400x400 pixels the time needed was 0.312 s on my pc.



For those who are interested in the code so far:



http://www.dmemos.de/onographic/onograph11/ono-graph11.lsp">//http://www.dmemos.de/onographic/onograph11/ono-graph11.lsp



http://www.dmemos.de/onographic/onograph11/ono-lines2.lsp">//http://www.dmemos.de/onographic/onograph11/ono-lines2.lsp



http://www.dmemos.de/onographic/onograph11/ono-rgb-ppm.lsp">//http://www.dmemos.de/onographic/onograph11/ono-rgb-ppm.lsp



I think i adapt the newLISP-gs style , so the next funtions will be draw-line, draw-path and so on .



PS:

I've found no solution for Cormullions issue, how can i generate a non-utf-char on a utf-system ?

Lutz

#10
After quickly looking through the code, I see only the newLISP function 'char' which is working differently on UTF-8 enabled versions. In file: http://www.dmemos.de/onographic/onograph11/ono-rgb-ppm.lsp">http://www.dmemos.de/onographic/onograp ... gb-ppm.lsp">http://www.dmemos.de/onographic/onograph11/ono-rgb-ppm.lsp change:


(define (ppm mrgb) (join (map char mrgb)))

to:


(define (ppm mrgb) (pack (dup "b" (length mrgb)) mrgb))

this will make the function work the same on both the UTF-8 and non-UTF-8 versions of newLISP.



On my Mac OS X system the new function is also more than double as fast than the old function using 'char'.

didi

#11
Thanks Lutz , this works if i call it direct with a list, but not with a variable representing a list,  here a short copy from my newLISP-GS monitor :



> yellow
(255 255 0)
> ( ppm yellow )
"000000"
> ( ppm '( 255 255 0 ) )
"25525500"
> ( list? yellow )
true
>


Maybe i didn't understand the pack-command .

Lutz

#12
that sounds impossible, it works for me:


> (define (ppm mrgb) (pack (dup "b" (length mrgb)) mrgb))
(lambda (mrgb) (pack (dup "b" (length mrgb)) mrgb))
> (set 'yellow '(255 255 0))
(255 255 0)
> (ppm yellow)
"25525500"
>


tested on the Mac OS X with the UTF-8 version and Win XP using the non-UTF-8 version in newLISP-GS



can you post a minimal but complete program to demonstrate that?

cormullion

#13
Works well here (Mac).



I thought that PPM was not immediately useful as a format. But I found that, on my Mac at least, there's a convert command which I believe is part of ImageMagick. So:


$ convert first.ppm first.png

convert these PPM files to PNG. Cool, eh?!



I'm hoping to play a bit more with this soon...

didi

#14
; part of ono-rgb-ppm2.lsp (rgb-mixer)
 
( set 'cmax 255 )
( set 'cmin 0 )
( set 'red ( list cmax cmin cmin ))
( set 'green ( list cmin cmax cmin ))

( define ( limit rgbx)
  ( if ( > rgbx cmax) cmax
   ( if ( < rgbx cmin) cmin rgbx )))

( define ( rgb-add rgb1 rgb2 )
( map limit ( map add rgb1 rgb2)))

( set 'yellow ( rgb-add red green ))

; translate rgb list to a string for ppm-format eg. ( 75 75 75 )  ->  "KKK"
(define (ppm mrgb) (pack (dup "b" (length mrgb)) mrgb))

( println ( ppm yellow ) )


leads to :

....

(255 255 0)

(lambda (mrgb) (pack (dup "b" (length mrgb)) mrgb))

"000000"



PS: Cormullion good! -  the same must exist for windows, but i have it not yet.