Drawing a line:

``````var myDraw = Draw(200, 200, true);
var x1 = randomInteger(200);
var y1 = randomInteger(200);
var x2 = randomInteger(200);
var y2 = randomInteger(200);
myDraw.line(x1, y1, x2, y2);
``````

Drawing many lines:

``````var myDraw = Draw(200, 200, true);

var makeLines = function(n, xs){
var x1 = randomInteger(200);
var y1 = randomInteger(200);
var x2 = randomInteger(200);
var y2 = randomInteger(200);
var xs2 = xs.concat([[x1, y1, x2, y2]]);
return (n==0) ? xs : makeLines(n-1, xs2);
}

var drawLines = function(lines){
var line = lines[0];
myDraw.line(line[0], line[1], line[2], line[3]);
if (lines.length > 1) {
drawLines(lines.slice(1));
}
}

var lines = makeLines(20, []);

drawLines(lines);
``````

``````var myDraw1 = Draw(200, 200, true);

var myDraw2 = Draw(200, 200, true);
``````

Computing the pixel-by-pixel distance between two images:

``````var myDraw1 = Draw(200, 200, false);

var myDraw2 = Draw(200, 200, false);

myDraw1.distance(myDraw2);
``````

Target image:

``````var targetImage = Draw(50, 50, true);
``````

Inferring lines that match the target image:

``````var targetImage = Draw(50, 50, false);

var drawLines = function(drawObj, lines){
var line = lines[0];
drawObj.line(line[0], line[1], line[2], line[3]);
if (lines.length > 1) {
drawLines(drawObj, lines.slice(1));
}
}

var makeLines = function(n, lines, prevScore){
// Add a random line to the set of lines
var x1 = randomInteger(50);
var y1 = randomInteger(50);
var x2 = randomInteger(50);
var y2 = randomInteger(50);
var newLines = lines.concat([[x1, y1, x2, y2]]);
// Compute image from set of lines
var generatedImage = Draw(50, 50, false);
drawLines(generatedImage, newLines);
// Factor prefers images that are close to target image
var newScore = -targetImage.distance(generatedImage)/1000; // Increase to 10000 to see more diverse samples
factor(newScore - prevScore);
generatedImage.destroy();
// Generate remaining lines (unless done)
return (n==1) ? newLines : makeLines(n-1, newLines, newScore);
}

Infer({
method: 'SMC',
particles: 100,
model() {
var lines = makeLines(4, [], 0);
var finalGeneratedImage = Draw(50, 50, true);
drawLines(finalGeneratedImage, lines);
}
})

'done'
``````

Inference using MCMC and with a model that can manipulate opacity and stroke width:

``````///fold:
var targetImage = Draw(50, 50, false);

var uniformDraw = function(xs){
var i = randomInteger(xs.length);
return xs[i];
}

var drawLines = function(drawObj, lines){
var line = lines[0];
drawObj.line(line[0], line[1], line[2], line[3], line[4], line[5]);
if (lines.length > 1) {
drawLines(drawObj, lines.slice(1));
}
}

var randomStrokeWidth = function(){
var widths = [2, 4, 8, 16];
return uniformDraw(widths);
}

var randomOpacity = function(){
var opacities = [0, .5];
return uniformDraw(opacities);
}

var makeLines = function(n, lines){
var x1 = randomInteger(50);
var y1 = randomInteger(50);
var x2 = randomInteger(50);
var y2 = randomInteger(50);
var strokeWidth = randomStrokeWidth();
var opacity = randomOpacity();
var newLines = lines.concat([[x1, y1, x2, y2, strokeWidth, opacity]]);
return (n==1) ? newLines : makeLines(n-1, newLines);
}

var finalImgSampler = Infer({
method: 'MCMC',
samples: 500,
model() {
var lines = makeLines(4, []);
var finalGeneratedImage = Draw(50, 50, true);
drawLines(finalGeneratedImage, lines);
var newScore = -targetImage.distance(finalGeneratedImage)/1000; // Increase to 10000 to see more diverse samples
factor(newScore);
// print(newScore);
return lines
}
});
///

var finalImage = Draw(100, 100, false);
var finalLines = sample(finalImgSampler);
drawLines(finalImage, finalLines);
``````

A more colorful target image:

``````var targetImage = Draw(50, 50, true);
``````

A richer image prior:

``````///fold:
var targetImage = Draw(50, 50, false);

var uniformDraw = function(xs){
var i = randomInteger(xs.length);
return xs[i];
}

var drawLines = function(drawObj, lines){
var line = lines[0];
drawObj.line(line[0], line[1], line[2], line[3], line[4], line[5], line[6]);
if (lines.length > 1) {
drawLines(drawObj, lines.slice(1));
}
}

var randomStrokeWidth = function(){
var widths = [2, 4, 8, 16];
return uniformDraw(widths);
}

var randomOpacity = function(){
var opacities = [0, 0.2, .5];
return uniformDraw(opacities);
}

var _getRandomColor = function(i) {
if (i == 0){
return "";
} else {
// var letters = '0123456789ABCDEF'.split('');
var color = '#';
return uniformDraw('04AF') + _getRandomColor(i-1);
}
}

var randomColor = function(){
return "#" + _getRandomColor(6);
}

var makeLines = function(n, lines){
var x1 = randomInteger(50);
var y1 = randomInteger(50);
var x2 = randomInteger(50);
var y2 = y1;
var strokeWidth = randomStrokeWidth();
var opacity = randomOpacity();
var color = randomColor();
var newLines = lines.concat([[x1, y1, x2, y2, strokeWidth, opacity, color]]);
return (n==1) ? newLines : makeLines(n-1, newLines);
}
///

var counter = [];

Infer({
method: 'MCMC',
samples: 2500,
model() {
var lines = makeLines(8, []);

var showOutputImage = (counter.length % 100 == 0);
var finalGeneratedImage = Draw(50, 50, showOutputImage);

drawLines(finalGeneratedImage, lines);
var newScore = -targetImage.distance(finalGeneratedImage)/1000; // Increase to 10000 to see more diverse samples
factor(newScore);

if (!showOutputImage) {
finalGeneratedImage.destroy()
}

counter.push(1);

return lines
}
})

// show target image for comparison