lj11

Marry Adobe Illustrator and Newlisp

Here is my old post from livejournal. I’ve decided to move it to the current blog, as its topic is about some technics in mapmaking.

Now we have got a visa-free border zone between Russian and Norway. And I work on the town map for coming Norwegian visitors. I almost finished the work, and at the end experiment with some not very important issues. In this post I want to show how I got rid of smooth color surface and made a texture, using Adobe Illustrator (abbrev. AI) scripting possibilities.

lj1

I can create texture by drawing green square and put lighter dots in the random order by hand.

lj2

The problem is that hand tends to put elements following some order, not absolutely randomly. And also it is tiresome to add hundreds of dots — textures are very greedy for number of low-contrasted elements. To overcome this I will generate coordinates of dots by computer and then will add them to the Illustartor document with help of the script.

First, to use ExtendScript — the dialect of javascript for AI, I download and install ExtendScript Toolkit. As I use AI CS2, I take installation file from here: http://www.adobe.com/support/downloads/product.jsp?product=111&platform=Windows

Toolkit allows debugging, but this time I will use it just as a code editor.

Javascript is as fine to get random coordinates, but I love newlisp and wouldn’t let it to stay aside. So I also use newlisp for Windows. It can be downloaded from this page: http://www.newlisp.org/index.cgi?page=Downloads The package contains Java GUI, in which I write the code, random_coor.lsp:

lj3

You see the code in the part above. In the part below is a very convenient REPL console, I usually try complex lisp expressions there before writing them in the code.

The code that generates random coordinates, radiuses and colors, and then writes them all into the file data.txt:

(set 'fileh (open "c:/prozion/sandbox/aics2/data.txt" "write"))
(set 'x0 -200 'y0 -200) ; coordinates of pattern square
(set 'X 20 'Y 20) ; size of pattern square in mm
(set 'R1 0.07 'R2 0.1) ; minimal and maximal radius

(define (mm2pt x) ; translates millimeters to points, internal units of measurement in AI
 (div x 0.35278))

(define (float-rand x digits)
 (div (rand (mul x (pow 10 digits))) (pow 10 digits)))

(define (rand3 x) (float-rand x 3))

; clean file
(write fileh "")

(dotimes (i 5000)
 (set 'radius (add R1 (div (rand (mul (sub R2 R1) 10000)) 10000)))
 (write-line fileh (string (mm2pt (add x0 (rand3 X))) " " (mm2pt (add y0 (rand3 Y))) " " (mm2pt radius) " " (+ 1 (rand 6)))))

(close fileh)

Look, I want to have 5000 dots! Imagine how I would do it all the time clicking mouse by hand in Illustrator! 🙂

Ok, file is ready. Now I open ExtendScript Toolkit and write the code, that extracts data from file data.txt, and creates a lo-oot of small circles:

lj4

Code RandomDots.js:

app.defaultStroked = true;
app.defaultFilled = true;

var doc = app.activeDocument;
if( doc.layers["@script"])
 layer = doc.layers["@script"];
else 
 layer = doc.layers[0];

// read data from file C:\\prozion\\sandbox\\aics2\\data.txt
var f = new File("/c/prozion/sandbox/aics2/data.txt");
f.open();
txt = f.read().split("\n");
for (i=0; i < txt.length; i++){
 values = txt[i].split(' ');
 if (values.length == 4) {
  x = parseFloat(values[0]);
  y = parseFloat(values[1]);
  r = parseFloat(values[2]);
  color = "a"+parseInt(values[3]);
  pi = layer.pathItems.ellipse(x,y,r,r);
  pi.fillColor = doc.swatches[color].color; 
}}
f.close();

After the code is ready I save it into the script folder of AI. My path to script folder looks so: C:\Program Files\Adobe\Adobe Illustrator CS2\Presets\Scripts

Go to Illustrator, create green square, with size according to the script random_coor.lsp: 20mm x 20mm. Set top-left corner of the square to (-200mm, -180mm), so dots will be generated strictly inside its bounds. Run the script:

lj5

Get the dots:

lj6

In closer view:

lj7

Circles have different colors, as I also chose color randomly from the set of swatches:

lj8

Now, unit of pattern is ready, all I have to do it is select square and dots and drag them onto the swatch palette:

lj9

And assign the background of «whereis» map

lj10

to the new pattern swatch:

lj11

Zoomed:

lj12

No big difference, but hopefully looks better for subconciousness.

Thanks Newlisp, thanks Javascript, thanks Illustrator!