<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity:60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0em 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0em 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
.wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0em;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0em 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0em 1em;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0em 0.25em; padding:0em 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px 1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none ! important;}
#displayArea {margin: 1em 1em 0em 1em;}
/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
noscript {display:none;}
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:
* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* MainMenu: The menu (usually on the left)
* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These InterfaceOptions for customising TiddlyWiki are saved in your browser

Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs)

<<option txtUserName>>
<<option chkSaveBackups>> SaveBackups
<<option chkAutoSave>> AutoSave
<<option chkRegExpSearch>> RegExpSearch
<<option chkCaseSensitiveSearch>> CaseSensitiveSearch
<<option chkAnimate>> EnableAnimations

----
Also see AdvancedOptions
<<importTiddlers>>
/***
|''Name:''|ProcessingPlugin|
|''Description:''|TiddlyWiki Bundle of John Ressig's processing.js|
|''Date:''|May 9, 2008|
|''Author:''|PaulDowney (psd (at) osmosoft (dot) com)|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/PaulDowney/plugins/ProcessingPlugin.js|
|''Version:''|0.2|
|''License:''|[[MIT license]]|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''~CoreVersion:''|2.2|

With contributions from Simon Baird.

***/

//{{{
// Ensure Plugin is only installed once.
if(!version.extensions.Processingjs) {
version.extensions.Processingjs = {installed:true};

config.macros.Processing = {
	counter: 0,
	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		var id = "processingcanvas"+this.counter;
		var canvas = createTiddlyElement(place,"canvas",id);

		// inlined code
		var code = paramString;

		// quick and dirty grab of code from a named tiddler
		if (store.tiddlerExists(params[0])) {
			code = store.getTiddlerText(params[0]);
		}

		// or with no params, grab code from this tiddler
		if (paramString.trim() == '') {
			code = tiddler.text;
		}

		createTiddlyElement(place,"br");
		var restartBtn = createTiddlyButton(place,"restart","restart",function() {
				story.refreshTiddler(tiddler.title,null,true);
				return false;
			},
			'processingRestart' // it's a class so you can style the button
		);

		Processing(canvas,code);
	}
};

// requires 2.4
merge(config.macros.view.views,{
	processing: function(value,place,params,wikifier,paramString,tiddler) {
		wikify("<<Processing\n"+value+"\n>>",place,highlightHack,tiddler);
	}
});

/*
 *  inlined copy of Processing.js
 *  latest code at: http://ejohn.org/blog/processingjs/
 */

/*
 * Processing.js - John Resig (http://ejohn.org/)
 * MIT Licensed
 * http://ejohn.org/blog/processingjs/
 *
 * This is a port of the Processing Visualization Language.
 * More information: http://processing.org/
 */

(function(){

this.Processing = function Processing( aElement, aCode )
{
  var p = buildProcessing( aElement );
  p.init( aCode );
  return p;
};

function log()
{
  try
  {
    console.log.apply( console, arguments );
  }
  catch(e)
  {
    try
    {
      opera.postError.apply( opera, arguments );
    }
    catch(e){}
  }
}

function parse( aCode, p )
{
  // Angels weep at this parsing code :-(

  // Remove end-of-line comments
  aCode = aCode.replace(/\/\/ .*\n/g, "\n");

  // Weird parsing errors with %
  aCode = aCode.replace(/([^\s])%([^\s])/g, "$1 % $2");
 
  // Simple convert a function-like thing to function
  aCode = aCode.replace(/(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g, function(all, type, name, args)
  {
    if ( name == "if" || name == "for" || name == "while" )
    {
      return all;
    }
    else
    {
      return "Processing." + name + " = function " + name + args;
    }
  });

  // Force .length() to be .length
  aCode = aCode.replace(/\.length\(\)/g, ".length");

  // foo( int foo, float bar )
  aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4");
  aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4");

  // float[] foo = new float[5];
  aCode = aCode.replace(/new (\w+)((?:\[([^\]]*)\])+)/g, function(all, name, args)
  {
    return "new ArrayList(" + args.slice(1,-1).split("][").join(", ") + ")";
  });
  
  aCode = aCode.replace(/(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g, function(all)
  {
    return all.replace(/{/g, "[").replace(/}/g, "]");
  });

  // int|float foo;
  var intFloat = /(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i;
  while ( intFloat.test(aCode) )
  {
    aCode = aCode.replace(new RegExp(intFloat), function(all, type, name, sep)
    {
      return type + " " + name + " = 0" + sep;
    });
  }

  // float foo = 5;
  aCode = aCode.replace(/(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g, function(all, type, arr, name, sep)
  {
    if ( type == "return" )
      return all;
    else
      return "var " + name + sep;
  });

  // Fix Array[] foo = {...} to [...]
  aCode = aCode.replace(/=\s*{((.|\s)*?)};/g, function(all,data)
  {
    return "= [" + data.replace(/{/g, "[").replace(/}/g, "]") + "]";
  });
  
  // static { ... } blocks
  aCode = aCode.replace(/static\s*{((.|\n)*?)}/g, function(all, init)
  {
    // Convert the static definitons to variable assignments
    //return init.replace(/\((.*?)\)/g, " = $1");
    return init;
  });

  // super() is a reserved word
  aCode = aCode.replace(/super\(/g, "superMethod(");

  var classes = ["int", "float", "boolean", "string"];

  function ClassReplace(all, name, extend, vars, last)
  {
    classes.push( name );

    var static = "";

    vars = vars.replace(/final\s+var\s+(\w+\s*=\s*.*?;)/g, function(all,set)
    {
      static += " " + name + "." + set;
      return "";
    });

    // Move arguments up from constructor and wrap contents with
    // a with(this), and unwrap constructor
    return "function " + name + "() {with(this){\n  " +
      (extend ? "var __self=this;function superMethod(){extendClass(__self,arguments," + extend + ");}\n" : "") +
      // Replace var foo = 0; with this.foo = 0;
      // and force var foo; to become this.foo = null;
      vars
        .replace(/,\s?/g, ";\n  this.")
        .replace(/\b(var |final |public )+\s*/g, "this.")
        .replace(/this.(\w+);/g, "this.$1 = null;") + 
	(extend ? "extendClass(this, " + extend + ");\n" : "") +
        "<CLASS " + name + " " + static + ">" + (typeof last == "string" ? last : name + "(");
  }

  var matchClasses = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g;
  var matchNoCon = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g;
  
  aCode = aCode.replace(matchClasses, ClassReplace);
  aCode = aCode.replace(matchNoCon, ClassReplace);

  var matchClass = /<CLASS (\w+) (.*?)>/, m;
  
  while ( (m = aCode.match( matchClass )) )
  {
    var left = RegExp.leftContext,
      allRest = RegExp.rightContext,
      rest = nextBrace(allRest),
      className = m[1],
      staticVars = m[2] || "";
      
    allRest = allRest.slice( rest.length + 1 );

    rest = rest.replace(new RegExp("\\b" + className + "\\(([^\\)]*?)\\)\\s*{", "g"), function(all, args)
    {
      args = args.split(/,\s*?/);
      
      if ( args[0].match(/^\s*$/) )
        args.shift();
      
      var fn = "if ( arguments.length == " + args.length + " ) {\n";
        
      for ( var i = 0; i < args.length; i++ )
      {
        fn += "    var " + args[i] + " = arguments[" + i + "];\n";
      }
        
      return fn;
    });
    
    // Fix class method names
    // this.collide = function() { ... }
    // and add closing } for with(this) ...
    rest = rest.replace(/(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g, function(all, name, args)
    {
      return "ADDMETHOD(this, '" + name + "', function(" + args + ")";
    });
    
    var matchMethod = /ADDMETHOD([\s\S]*?{)/, mc;
    var methods = "";
    
    while ( (mc = rest.match( matchMethod )) )
    {
      var prev = RegExp.leftContext,
        allNext = RegExp.rightContext,
        next = nextBrace(allNext);

      methods += "addMethod" + mc[1] + next + "});"
      
      rest = prev + allNext.slice( next.length + 1 );
      
    }

    rest = methods + rest;
    
    aCode = left + rest + "\n}}" + staticVars + allRest;
  }

  // Do some tidying up, where necessary
  aCode = aCode.replace(/Processing.\w+ = function addMethod/g, "addMethod");
  
  function nextBrace( right )
  {
    var rest = right;
    var position = 0;
    var leftCount = 1, rightCount = 0;
    
    while ( leftCount != rightCount )
    {
      var nextLeft = rest.indexOf("{");
      var nextRight = rest.indexOf("}");
      
      if ( nextLeft < nextRight && nextLeft != -1 )
      {
        leftCount++;
        rest = rest.slice( nextLeft + 1 );
        position += nextLeft + 1;
      }
      else
      {
        rightCount++;
        rest = rest.slice( nextRight + 1 );
        position += nextRight + 1;
      }
    }
    
    return right.slice(0, position - 1);
  }

  // Handle (int) Casting
  aCode = aCode.replace(/\(int\)/g, "0|");

  // Remove Casting
  aCode = aCode.replace(new RegExp("\\((" + classes.join("|") + ")(\\[\\])?\\)", "g"), "");
  
  // Convert 3.0f to just 3.0
  aCode = aCode.replace(/(\d+)f/g, "$1");

  // Force numbers to exist
  //aCode = aCode.replace(/([^.])(\w+)\s*\+=/g, "$1$2 = ($2||0) +");

  // Force characters-as-bytes to work
  aCode = aCode.replace(/('[a-zA-Z0-9]')/g, "$1.charCodeAt(0)");

  // Convert #aaaaaa into color
  aCode = aCode.replace(/#([a-f0-9]{6})/ig, function(m, hex){
    var num = toNumbers(hex);
    return "color(" + num[0] + "," + num[1] + "," + num[2] + ")";
  });

  function toNumbers( str ){
    var ret = [];
     str.replace(/(..)/g, function(str){
      ret.push( parseInt( str, 16 ) );
    });
    return ret;
  }

//log(aCode);

  return aCode;
}

function buildProcessing( curElement ){

  var p = {};

  // init
  p.PI = Math.PI;
  p.TWO_PI = 2 * p.PI;
  p.HALF_PI = p.PI / 2;
  p.P3D = 3;
  p.CORNER = 0;
  p.CENTER = 1;
  p.CENTER_RADIUS = 2;
  p.RADIUS = 2;
  p.POLYGON = 1;
  p.TRIANGLES = 6;
  p.POINTS = 7;
  p.LINES = 8;
  p.TRIANGLE_STRIP = 9;
  p.CORNERS = 10;
  p.CLOSE = true;
  p.RGB = 1;
  p.HSB = 2;

  // "Private" variables used to maintain state
  var curContext = curElement.getContext("2d");
  var doFill = true;
  var doStroke = true;
  var loopStarted = false;
  var hasBackground = false;
  var doLoop = true;
  var curRectMode = p.CORNER;
  var curEllipseMode = p.CENTER;
  var inSetup = false;
  var inDraw = false;
  var curBackground = "rgba(204,204,204,1)";
  var curFrameRate = 1000;
  var curShape = p.POLYGON;
  var curShapeCount = 0;
  var opacityRange = 255;
  var redRange = 255;
  var greenRange = 255;
  var blueRange = 255;
  var pathOpen = false;
  var mousePressed = false;
  var keyPressed = false;
  var firstX, firstY, prevX, prevY;
  var curColorMode = p.RGB;
  var curTint = -1;
  var curTextSize = 12;
  var curTextFont = "Arial";
  var getLoaded = false;
  var start = (new Date).getTime();

  // Global vars for tracking mouse position
  p.pmouseX = 0;
  p.pmouseY = 0;
  p.mouseX = 0;
  p.mouseY = 0;

  // Will be replaced by the user, most likely
  p.mouseDragged = undefined;
  p.mouseMoved = undefined;
  p.mousePressed = undefined;
  p.mouseReleased = undefined;
  p.keyPressed = undefined;
  p.keyReleased = undefined;
  p.draw = undefined;
  p.setup = undefined;

  // The height/width of the canvas
  p.width = curElement.width - 0;
  p.height = curElement.height - 0;
  
  // In case I ever need to do HSV conversion:
  // http://srufaculty.sru.edu/david.dailey/javascript/js/5rml.js
  p.color = function color( aValue1, aValue2, aValue3, aValue4 )
  {
    var aColor = "";
    
    if ( arguments.length == 3 )
    {
      aColor = p.color( aValue1, aValue2, aValue3, opacityRange );
    }
    else if ( arguments.length == 4 )
    {
      var a = aValue4 / opacityRange;
      a = isNaN(a) ? 1 : a;

      if ( curColorMode == p.HSB )
      {
        var rgb = HSBtoRGB(aValue1, aValue2, aValue3);
        var r = rgb[0], g = rgb[1], b = rgb[2];
      }
      else
      {
        var r = getColor(aValue1, redRange);
        var g = getColor(aValue2, greenRange);
        var b = getColor(aValue3, blueRange);
      }

      aColor = "rgba(" + r + "," + g + "," + b + "," + a + ")";
    }
    else if ( typeof aValue1 == "string" )
    {
      aColor = aValue1;

      if ( arguments.length == 2 )
      {
        var c = aColor.split(",");
	c[3] = (aValue2 / opacityRange) + ")";
	aColor = c.join(",");
      }
    }
    else if ( arguments.length == 2 )
    {
      aColor = p.color( aValue1, aValue1, aValue1, aValue2 );
    }
    else if ( typeof aValue1 == "number" )
    {
      aColor = p.color( aValue1, aValue1, aValue1, opacityRange );
    }
    else
    {
      aColor = p.color( redRange, greenRange, blueRange, opacityRange );
    }

    // HSB conversion function from Mootools, MIT Licensed
    function HSBtoRGB(h, s, b)
    {
      h = (h / redRange) * 100;
      s = (s / greenRange) * 100;
      b = (b / blueRange) * 100;
      if (s == 0){
        return [b, b, b];
      } else {
        var hue = h % 360;
        var f = hue % 60;
        var br = Math.round(b / 100 * 255);
        var p = Math.round((b * (100 - s)) / 10000 * 255);
        var q = Math.round((b * (6000 - s * f)) / 600000 * 255);
        var t = Math.round((b * (6000 - s * (60 - f))) / 600000 * 255);
        switch (Math.floor(hue / 60)){
          case 0: return [br, t, p];
          case 1: return [q, br, p];
          case 2: return [p, br, t];
          case 3: return [p, q, br];
          case 4: return [t, p, br];
          case 5: return [br, p, q];
        }
      }
    }

    function getColor( aValue, range )
    {
      return Math.round(255 * (aValue / range));
    }
    
    return aColor;
  }

  p.nf = function( num, pad )
  {
    var str = "" + num;
    while ( pad - str.length )
      str = "0" + str;
    return str;
  };

  p.AniSprite = function( prefix, frames )
  {
    this.images = [];
    this.pos = 0;

    for ( var i = 0; i < frames; i++ )
    {
      this.images.push( prefix + p.nf( i, ("" + frames).length ) + ".gif" );
    }

    this.display = function( x, y )
    {
      p.image( this.images[ this.pos ], x, y );

      if ( ++this.pos >= frames )
        this.pos = 0;
    };

    this.getWidth = function()
    {
      return getImage(this.images[0]).width;
    };

    this.getHeight = function()
    {
      return getImage(this.images[0]).height;
    };
  };

  function buildImageObject( obj )
  {
    var pixels = obj.data;
    var data = p.createImage( obj.width, obj.height );

    if ( data.__defineGetter__ && data.__lookupGetter__ && !data.__lookupGetter__("pixels") )
    {
      var pixelsDone;
      data.__defineGetter__("pixels", function()
      {
        if ( pixelsDone )
	  return pixelsDone;

	pixelsDone = [];

        for ( var i = 0; i < pixels.length; i += 4 )
        {
          pixelsDone.push( p.color(pixels[i], pixels[i+1], pixels[i+2], pixels[i+3]) );
        }

	return pixelsDone;
      });
    }
    else
    {
      data.pixels = [];

      for ( var i = 0; i < pixels.length; i += 4 )
      {
        data.pixels.push( p.color(pixels[i], pixels[i+1], pixels[i+2], pixels[i+3]) );
      }
    }

    return data;
  }

  p.createImage = function createImage( w, h, mode )
  {
    var data = {
      width: w,
      height: h,
      pixels: new Array( w * h ),
      get: function(x,y)
      {
        return this.pixels[w*y+x];
      },
      _mask: null,
      mask: function(img)
      {
        this._mask = img;
      },
      loadPixels: function()
      {
      },
      updatePixels: function()
      {
      }
    };

    return data;
  }

  p.createGraphics = function createGraphics( w, h )
  {
    var canvas = document.createElement("canvas");
    var ret = buildProcessing( canvas );
    ret.size( w, h );
    ret.canvas = canvas;
    return ret;
  }

  p.beginDraw = function beginDraw()
  {

  }

  p.endDraw = function endDraw()
  {

  }

  p.tint = function tint( rgb, a )
  {
    curTint = a;
  }

  function getImage( img ) {
    if ( typeof img == "string" )
    {
      return document.getElementById(img);
    }

    if ( img.img || img.canvas )
    {
      return img.img || img.canvas;
    }

    img.data = [];

    for ( var i = 0, l = img.pixels.length; i < l; i++ )
    {
      var c = (img.pixels[i] || "rgba(0,0,0,1)").slice(5,-1).split(",");
      img.data.push( parseInt(c[0]), parseInt(c[1]), parseInt(c[2]), parseFloat(c[3]) * 100 );
    }

    var canvas = document.createElement("canvas")
    canvas.width = img.width;
    canvas.height = img.height;
    var context = canvas.getContext("2d");
    context.putImageData( img, 0, 0 );

    img.canvas = canvas;

    return canvas;
  }

  p.image = function image( img, x, y, w, h )
  {
    x = x || 0;
    y = y || 0;

    var obj = getImage(img);

    if ( curTint >= 0 )
    {
      var oldAlpha = curContext.globalAlpha;
      curContext.globalAlpha = curTint / opacityRange;
    }

    if ( arguments.length == 3 )
    {
      curContext.drawImage( obj, x, y );
    }
    else
    {
      curContext.drawImage( obj, x, y, w, h );
    }

    if ( curTint >= 0 )
    {
      curContext.globalAlpha = oldAlpha;
    }

    if ( img._mask )
    {
      var oldComposite = curContext.globalCompositeOperation;
      curContext.globalCompositeOperation = "darker";
      p.image( img._mask, x, y );
      curContext.globalCompositeOperation = oldComposite;
    }
  }

  p.exit = function exit()
  {

  }

  p.save = function save( file )
  {

  }

  p.loadImage = function loadImage( file )
  {
    var img = document.getElementById(file);
    if ( !img )
      return;

    var h = img.height, w = img.width;

    var canvas = document.createElement("canvas");
    canvas.width = w;
    canvas.height = h;
    var context = canvas.getContext("2d");

    context.drawImage( img, 0, 0 );
    var data = buildImageObject( context.getImageData( 0, 0, w, h ) );
    data.img = img;
    return data;
  }

  p.loadFont = function loadFont( name )
  {
    return {
      name: name,
      width: function( str )
      {
        if ( curContext.mozMeasureText )
          return curContext.mozMeasureText( typeof str == "number" ?
            String.fromCharCode( str ) :
            str) / curTextSize;
	else
	  return 0;
      }
    };
  }

  p.textFont = function textFont( name, size )
  {
    curTextFont = name;
    p.textSize( size );
  }

  p.textSize = function textSize( size )
  {
    if ( size )
    {
      curTextSize = size;
    }
  }

  p.textAlign = function textAlign()
  {

  }

  p.text = function text( str, x, y )
  {
    if ( str && curContext.mozDrawText )
    {
      curContext.save();
      curContext.mozTextStyle = curTextSize + "px " + curTextFont.name;
      curContext.translate(x, y);
      curContext.mozDrawText( typeof str == "number" ?
        String.fromCharCode( str ) :
	str );
      curContext.restore();
    }
  }

  p.char = function char( key )
  {
    //return String.fromCharCode( key );
    return key;
  }

  p.println = function println()
  {

  }

  p.map = function map( value, istart, istop, ostart, ostop )
  {
    return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
  };

  String.prototype.replaceAll = function(re, replace)
  {
    return this.replace(new RegExp(re, "g"), replace);
  };

  p.Point = function Point( x, y )
  {
    this.x = x;
    this.y = y;
    this.copy = function()
    {
      return new Point( x, y );
    }
  }

  p.Random = function()
  {
    var haveNextNextGaussian = false;
    var nextNextGaussian;

    this.nextGaussian = function()
    {
      if (haveNextNextGaussian) {
        haveNextNextGaussian = false;

        return nextNextGaussian;
      } else {
        var v1, v2, s;
        do { 
          v1 = 2 * p.random(1) - 1;   // between -1.0 and 1.0
          v2 = 2 * p.random(1) - 1;   // between -1.0 and 1.0
          s = v1 * v1 + v2 * v2;
        } while (s >= 1 || s == 0);
        var multiplier = Math.sqrt(-2 * Math.log(s)/s);
        nextNextGaussian = v2 * multiplier;
        haveNextNextGaussian = true;

        return v1 * multiplier;
      }
    };
  }

  p.ArrayList = function ArrayList( size, size2, size3 )
  {
    var array = new Array( 0 | size );
    
    if ( size2 )
    {
      for ( var i = 0; i < size; i++ )
      {
        array[i] = [];

        for ( var j = 0; j < size2; j++ )
        {
	  var a = array[i][j] = size3 ? new Array( size3 ) : 0;
	  for ( var k = 0; k < size3; k++ )
	  {
	    a[k] = 0;
	  }
        }
      }
    }
    else
    {
      for ( var i = 0; i < size; i++ )
      {
        array[i] = 0;
      }
    }
    
    array.size = function()
    {
      return this.length;
    };
    array.get = function( i )
    {
      return this[ i ];
    };
    array.remove = function( i )
    {
      return this.splice( i, 1 );
    };
    array.add = function( item )
    {
      for ( var i = 0; this[ i ] != undefined; i++ ) {}
      this[ i ] = item;
    };
    array.clone = function()
    {
      var a = new ArrayList( size );
      for ( var i = 0; i < size; i++ )
      {
        a[ i ] = this[ i ];
      }
      return a;
    };
    array.isEmpty = function()
    {
      return !this.length;
    };
    array.clear = function()
    {
      this.length = 0;
    };
    
    return array;
  }
  
  p.colorMode = function colorMode( mode, range1, range2, range3, range4 )
  {
    curColorMode = mode;

    if ( arguments.length >= 4 )
    {
      redRange = range1;
      greenRange = range2;
      blueRange = range3;
    }

    if ( arguments.length == 5 )
    {
      opacityRange = range4;
    }

    if ( arguments.length == 2 )
    {
      p.colorMode( mode, range1, range1, range1, range1 );
    }
  }
  
  p.beginShape = function beginShape( type )
  {
    curShape = type;
    curShapeCount = 0; 
  }
  
  p.endShape = function endShape( close )
  {
    if ( curShapeCount != 0 )
    {
      curContext.lineTo( firstX, firstY );

      if ( doFill )
        curContext.fill();
        
      if ( doStroke )
        curContext.stroke();
    
      curContext.closePath();
      curShapeCount = 0;
      pathOpen = false;
    }

    if ( pathOpen )
    {
      curContext.closePath();
    }
  }
  
  p.vertex = function vertex( x, y, x2, y2, x3, y3 )
  {
    if ( curShapeCount == 0 && curShape != p.POINTS )
    {
      pathOpen = true;
      curContext.beginPath();
      curContext.moveTo( x, y );
    }
    else
    {
      if ( curShape == p.POINTS )
      {
        p.point( x, y );
      }
      else if ( arguments.length == 2 )
      {
        if ( curShape == p.TRIANGLE_STRIP && curShapeCount == 2 )
	{
          curContext.moveTo( prevX, prevY );
          curContext.lineTo( firstX, firstY );
	}

        curContext.lineTo( x, y );
      }
      else if ( arguments.length == 4 )
      {
        if ( curShapeCount > 1 )
        {
	  curContext.moveTo( prevX, prevY );
          curContext.quadraticCurveTo( firstX, firstY, x, y );
	  curShapeCount = 1;
        }
      }
      else if ( arguments.length == 6 )
      {
        curContext.bezierCurveTo( x, y, x2, y2, x3, y3 );
        curShapeCount = -1;
      }
    }

    prevX = firstX;
    prevY = firstY;
    firstX = x;
    firstY = y;

    
    curShapeCount++;
    
    if ( curShape == p.LINES && curShapeCount == 2 ||
         (curShape == p.TRIANGLES || curShape == p.TRIANGLE_STRIP) && curShapeCount == 3 )
    {
      p.endShape();
    }

    if ( curShape == p.TRIANGLE_STRIP && curShapeCount == 3 )
    {
      curShapeCount = 2;
    }
  }

  p.curveTightness = function()
  {

  }

  // Unimplmented - not really possible with the Canvas API
  p.curveVertex = function( x, y, x2, y2 )
  {
    p.vertex( x, y, x2, y2 );
  }

  p.bezierVertex = p.vertex
  
  p.rectMode = function rectMode( aRectMode )
  {
    curRectMode = aRectMode;
  }

  p.imageMode = function()
  {

  }
  
  p.ellipseMode = function ellipseMode( aEllipseMode )
  {
    curEllipseMode = aEllipseMode;
  }
  
  p.dist = function dist( x1, y1, x2, y2 )
  {
    return Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) );
  }

  p.year = function year()
  {
    return (new Date).getYear() + 1900;
  }

  p.month = function month()
  {
    return (new Date).getMonth();
  }

  p.day = function day()
  {
    return (new Date).getDay();
  }

  p.hour = function hour()
  {
    return (new Date).getHours();
  }

  p.minute = function minute()
  {
    return (new Date).getMinutes();
  }

  p.second = function second()
  {
    return (new Date).getSeconds();
  }

  p.millis = function millis()
  {
    return (new Date).getTime() - start;
  }
  
  p.ortho = function ortho()
  {
  
  }
  
  p.translate = function translate( x, y )
  {
    curContext.translate( x, y );
  }
  
  p.scale = function scale( x, y )
  {
    curContext.scale( x, y || x );
  }
  
  p.rotate = function rotate( aAngle )
  {
    curContext.rotate( aAngle );
  }
  
  p.pushMatrix = function pushMatrix()
  {
    curContext.save();
  }
  
  p.popMatrix = function popMatrix()
  {
    curContext.restore();
  }
  
  p.redraw = function redraw()
  {
    if ( hasBackground )
    {
      p.background();
    }
    
    inDraw = true;
    p.pushMatrix();
    p.draw();
    p.popMatrix();
    inDraw = false;
  }
  
  p.loop = function loop()
  {
    if ( loopStarted )
      return;
    
    var looping = setInterval(function()
    {
      try
      {
        p.redraw();
      }
      catch(e)
      {
        clearInterval( looping );
        throw e;
      }
    }, 1000 / curFrameRate );
    
    loopStarted = true;
  }
  
  p.frameRate = function frameRate( aRate )
  {
    curFrameRate = aRate;
  }
  
  p.background = function background( img )
  {
    if ( arguments.length )
    {
      if ( img && img.img )
      {
        curBackground = img;
      }
      else
      {
        curBackground = p.color.apply( this, arguments );
      }
    }
    

    if ( curBackground.img )
    {
      p.image( curBackground, 0, 0 );
    }
    else
    {
      var oldFill = curContext.fillStyle;
      curContext.fillStyle = curBackground + "";
      curContext.fillRect( 0, 0, p.width, p.height );
      curContext.fillStyle = oldFill;
    }
  }

  p.sq = function sq( aNumber )
  {
    return aNumber * aNumber;
  }

  p.sqrt = function sqrt( aNumber )
  {
    return Math.sqrt( aNumber );
  }
  
  p.int = function int( aNumber )
  {
    return Math.floor( aNumber );
  }

  p.min = function min( aNumber, aNumber2 )
  {
    return Math.min( aNumber, aNumber2 );
  }

  p.max = function max( aNumber, aNumber2 )
  {
    return Math.max( aNumber, aNumber2 );
  }

  p.ceil = function ceil( aNumber )
  {
    return Math.ceil( aNumber );
  }

  p.floor = function floor( aNumber )
  {
    return Math.floor( aNumber );
  }

  p.float = function float( aNumber )
  {
    return typeof aNumber == "string" ?
	p.float( aNumber.charCodeAt(0) ) :
        parseFloat( aNumber );
  }

  p.byte = function byte( aNumber )
  {
    return aNumber || 0;
  }
  
  p.random = function random( aMin, aMax )
  {
    return arguments.length == 2 ?
      aMin + (Math.random() * (aMax - aMin)) :
      Math.random() * aMin;
  }

  // From: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
  p.noise = function( x, y, z )
  {
    return arguments.length >= 2 ?
      PerlinNoise_2D( x, y ) :
      PerlinNoise_2D( x, x );
  }

  function Noise(x, y)
  {
    var n = x + y * 57;
    n = (n<<13) ^ n;
    return Math.abs(1.0 - (((n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0));
  }

  function SmoothedNoise(x, y)
  {
    var corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
    var sides   = ( Noise(x-1, y)  +Noise(x+1, y)  +Noise(x, y-1)  +Noise(x, y+1) ) /  8;
    var center  =  Noise(x, y) / 4;
    return corners + sides + center;
  }

  function InterpolatedNoise(x, y)
  {
    var integer_X    = Math.floor(x);
    var fractional_X = x - integer_X;

    var integer_Y    = Math.floor(y);
    var fractional_Y = y - integer_Y;

    var v1 = SmoothedNoise(integer_X,     integer_Y);
    var v2 = SmoothedNoise(integer_X + 1, integer_Y);
    var v3 = SmoothedNoise(integer_X,     integer_Y + 1);
    var v4 = SmoothedNoise(integer_X + 1, integer_Y + 1);

    var i1 = Interpolate(v1 , v2 , fractional_X);
    var i2 = Interpolate(v3 , v4 , fractional_X);

    return Interpolate(i1 , i2 , fractional_Y);
  }

  function PerlinNoise_2D(x, y)
  {
      var total = 0;
      var p = 0.25;
      var n = 3;

      for ( var i = 0; i <= n; i++ )
      {
          var frequency = Math.pow(2, i);
          var amplitude = Math.pow(p, i);

          total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
      }

      return total;
  }

  function Interpolate(a, b, x)
  {
    var ft = x * p.PI;
    var f = (1 - p.cos(ft)) * .5;
    return  a*(1-f) + b*f;
  }

  p.red = function( aColor )
  {
    return parseInt(aColor.slice(5));
  }

  p.green = function( aColor )
  {
    return parseInt(aColor.split(",")[1]);
  }

  p.blue = function( aColor )
  {
    return parseInt(aColor.split(",")[2]);
  }

  p.alpha = function( aColor )
  {
    return parseInt(aColor.split(",")[3]);
  }

  p.abs = function abs( aNumber )
  {
    return Math.abs( aNumber );
  }
  
  p.cos = function cos( aNumber )
  {
    return Math.cos( aNumber );
  }
  
  p.sin = function sin( aNumber )
  {
    return Math.sin( aNumber );
  }
  
  p.pow = function pow( aNumber, aExponent )
  {
    return Math.pow( aNumber, aExponent );
  }
  
  p.constrain = function constrain( aNumber, aMin, aMax )
  {
    return Math.min( Math.max( aNumber, aMin ), aMax );
  }
  
  p.sqrt = function sqrt( aNumber )
  {
  	return Math.sqrt( aNumber );
  }
  
  p.atan2 = function atan2( aNumber, aNumber2 )
  {
  	return Math.atan2( aNumber, aNumber2 );
  }
  
  p.radians = function radians( aAngle )
  {
    return ( aAngle / 180 ) * p.PI;
  }
  
  p.size = function size( aWidth, aHeight )
  {
    var fillStyle = curContext.fillStyle;
    var strokeStyle = curContext.strokeStyle;

    curElement.width = p.width = aWidth;
    curElement.height = p.height = aHeight;

    curContext.fillStyle = fillStyle;
    curContext.strokeStyle = strokeStyle;
  }
  
  p.noStroke = function noStroke()
  {
    doStroke = false;
  }
  
  p.noFill = function noFill()
  {
    doFill = false;
  }
  
  p.smooth = function smooth()
  {
  
  }
  
  p.noLoop = function noLoop()
  {
    doLoop = false;
  }
  
  p.fill = function fill()
  {
    doFill = true;
    curContext.fillStyle = p.color.apply( this, arguments );
  }
  
  p.stroke = function stroke()
  {
    doStroke = true;
    curContext.strokeStyle = p.color.apply( this, arguments );
  }

  p.strokeWeight = function strokeWeight( w )
  {
    curContext.lineWidth = w;
  }
  
  p.point = function point( x, y )
  {
    var oldFill = curContext.fillStyle;
    curContext.fillStyle = curContext.strokeStyle;
    curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
    curContext.fillStyle = oldFill;
  }

  p.get = function get( x, y )
  {
    if ( arguments.length == 0 )
    {
      var c = p.createGraphics( p.width, p.height );
      c.image( curContext, 0, 0 );
      return c;
    }

    if ( !getLoaded )
    {
      getLoaded = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) );
    }

    return getLoaded.get( x, y );
  }

  p.set = function set( x, y, color )
  {
    var oldFill = curContext.fillStyle;
    curContext.fillStyle = color;
    curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
    curContext.fillStyle = oldFill;
  }
  
  p.arc = function arc( x, y, width, height, start, stop )
  {
    if ( width <= 0 )
      return;

    if ( curEllipseMode == p.CORNER )
    {
      x += width / 2;
      y += height / 2;
    }

    curContext.beginPath();
  
    curContext.moveTo( x, y );
    curContext.arc( x, y, curEllipseMode == p.CENTER_RADIUS ? width : width/2, start, stop, false );
    
    if ( doFill )
      curContext.fill();
      
    if ( doStroke )
      curContext.stroke();
    
    curContext.closePath();
  }
  
  p.line = function line( x1, y1, x2, y2 )
  {
    curContext.lineCap = "round";
    curContext.beginPath();
  
    curContext.moveTo( x1 || 0, y1 || 0 );
    curContext.lineTo( x2 || 0, y2 || 0 );
    
    curContext.stroke();
    
    curContext.closePath();
  }

  p.bezier = function bezier( x1, y1, x2, y2, x3, y3, x4, y4 )
  {
    curContext.lineCap = "butt";
    curContext.beginPath();
  
    curContext.moveTo( x1, y1 );
    curContext.bezierCurveTo( x2, y2, x3, y3, x4, y4 );
    
    curContext.stroke();
    
    curContext.closePath();
  }

  p.triangle = function triangle( x1, y1, x2, y2, x3, y3 )
  {
    p.beginShape();
    p.vertex( x1, y1 );
    p.vertex( x2, y2 );
    p.vertex( x3, y3 );
    p.endShape();
  }

  p.quad = function quad( x1, y1, x2, y2, x3, y3, x4, y4 )
  {
    p.beginShape();
    p.vertex( x1, y1 );
    p.vertex( x2, y2 );
    p.vertex( x3, y3 );
    p.vertex( x4, y4 );
    p.endShape();
  }
  
  p.rect = function rect( x, y, width, height )
  {
    if ( width == 0 && height == 0 )
      return;

    curContext.beginPath();
    
    var offsetStart = 0;
    var offsetEnd = 0;

    if ( curRectMode == p.CORNERS )
    {
      width -= x;
      height -= y;
    }
    
    if ( curRectMode == p.RADIUS )
    {
      width *= 2;
      height *= 2;
    }
    
    if ( curRectMode == p.CENTER || curRectMode == p.RADIUS )
    {
      x -= width / 2;
      y -= height / 2;
    }
  
    curContext.rect(
      Math.round( x ) - offsetStart,
      Math.round( y ) - offsetStart,
      Math.round( width ) + offsetEnd,
      Math.round( height ) + offsetEnd
    );
      
    if ( doFill )
      curContext.fill();
      
    if ( doStroke )
      curContext.stroke();
    
    curContext.closePath();
  }
  
  p.ellipse = function ellipse( x, y, width, height )
  {
    x = x || 0;
    y = y || 0;

    if ( width <= 0 && height <= 0 )
      return;

    curContext.beginPath();
    
    if ( curEllipseMode == p.RADIUS )
    {
      width *= 2;
      height *= 2;
    }
    
    var offsetStart = 0;
    
    // Shortcut for drawing a circle
    if ( width == height )
      curContext.arc( x - offsetStart, y - offsetStart, width / 2, 0, Math.PI * 2, false );
  
    if ( doFill )
      curContext.fill();
      
    if ( doStroke )
      curContext.stroke();
    
    curContext.closePath();
  }

  p.link = function( href, target )
  {
    window.location = href;
  }

  p.loadPixels = function()
  {
    p.pixels = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) ).pixels;
  }

  p.updatePixels = function()
  {
    var colors = /(\d+),(\d+),(\d+),(\d+)/;
    var pixels = {};
    var data = pixels.data = [];
    pixels.width = p.width;
    pixels.height = p.height;

    var pos = 0;

    for ( var i = 0, l = p.pixels.length; i < l; i++ ) {
      var c = (p.pixels[i] || "rgba(0,0,0,1)").match(colors);
      data[pos] = parseInt(c[1]);
      data[pos+1] = parseInt(c[2]);
      data[pos+2] = parseInt(c[3]);
      data[pos+3] = parseFloat(c[4]) * 100;
      pos += 4;
    }

    curContext.putImageData(pixels, 0, 0);
  }

  p.extendClass = function extendClass( obj, args, fn )
  {
    if ( arguments.length == 3 )
    {
      fn.apply( obj, args );
    }
    else
    {
      args.call( obj );
    }
  }

  p.addMethod = function addMethod( object, name, fn )
  {
    if ( object[ name ] )
    {
      var args = fn.length;
      
      var oldfn = object[ name ];
      object[ name ] = function()
      {
        if ( arguments.length == args )
          return fn.apply( this, arguments );
        else
          return oldfn.apply( this, arguments );
      };
    }
    else
    {
      object[ name ] = fn;
    }
  }

  p.init = function init(code){
    p.stroke( 0 );
    p.fill( 255 );
  
    // Canvas has trouble rendering single pixel stuff on whole-pixel
    // counts, so we slightly offset it (this is super lame).
    curContext.translate( 0.5, 0.5 );

    if ( code )
    {
      (function(Processing){with (p){
        eval(parse(code, p));
      }})(p);
    }
  
    if ( p.setup )
    {
      inSetup = true;
      p.setup();
    }
    
    inSetup = false;
    
    if ( p.draw )
    {
      if ( !doLoop )
      {
        p.redraw();
      }
      else
      {
        p.loop();
      }
    }
    
    attach( curElement, "mousemove", function(e)
    {
      p.pmouseX = p.mouseX;
      p.pmouseY = p.mouseY;
      p.mouseX = e.clientX - curElement.offsetLeft;
      p.mouseY = e.clientY - curElement.offsetTop;

      if ( p.mouseMoved )
      {
        p.mouseMoved();
      }      

      if ( mousePressed && p.mouseDragged )
      {
        p.mouseDragged();
      }      
    });
    
    attach( curElement, "mousedown", function(e)
    {
      mousePressed = true;

      if ( typeof p.mousePressed == "function" )
      {
        p.mousePressed();
      }
      else
      {
        p.mousePressed = true;
      }
    });
      
    attach( curElement, "mouseup", function(e)
    {
      mousePressed = false;

      if ( typeof p.mousePressed != "function" )
      {
        p.mousePressed = false;
      }

      if ( p.mouseReleased )
      {
        p.mouseReleased();
      }
    });

    attach( document, "keydown", function(e)
    {
      keyPressed = true;

      p.key = e.keyCode + 32;

      if ( e.shiftKey )
      {
        p.key = String.fromCharCode(p.key).toUpperCase().charCodeAt(0);
      }

      if ( typeof p.keyPressed == "function" )
      {
        p.keyPressed();
      }
      else
      {
        p.keyPressed = true;
      }
    });

    attach( document, "keyup", function(e)
    {
      keyPressed = false;

      if ( typeof p.keyPressed != "function" )
      {
        p.keyPressed = false;
      }

      if ( p.keyReleased )
      {
        p.keyReleased();
      }
    });

    function attach(elem, type, fn)
    {
      if ( elem.addEventListener )
        elem.addEventListener( type, fn, false );
      else
        elem.attachEvent( "on" + type, fn );
    }
  };

  return p;
}


})();


} //# end of "install only once"
//}}}

TiddlyProcessing
</div>
TiddlyProcessing
[[Basic Examples|BasicExample]]
ProcessingjsPlugin
Processing.js in TiddlyWiki
TiddlyProcessing

[[TiddlyWiki|http://tiddlywiki.com]], a wiki in a single HTML page. Open a [[Downloaded]] a copy of this page in Firefox, and you'll be able to edit the examples and save your changes locally on your computer. For more help on using TiddlyWiki, including support for other browsers, see [[Download Software|http://www.tiddlywiki.com/#DownloadSoftware]].

If you have questions, the ~TiddlyWiki community is incredibly helpful - there's a [[developer's group|http://groups.google.com/group/TiddlyWikiDev]] and a [[user's group|http://groups.google.com/group/TiddlyWiki]] on Google Groups. 
TiddlyProcessing is a TiddlyWiki containing [[John Ressig|http://ejohn.org]]'s [[Processing.js|http://ejohn.org/apps/processing.js/]] [[basic examples|BasicExample]]. Double click an example, e.g. [[Clock]] to view and edit the source. Most of the examples work, with the notable exception of those involving images.  [[Download|./download.php]] this file and reopen it in Firefox to save your work.

[[Simon Baird|http://simonbaird.com/]] has made some great tweaks and examples, and put [[his version|http://tiddlyprocessing-simon.tiddlyspot.com]] up on [[TiddlySpot|http://tiddlyspot.com]], a great place to store your ~TiddlyWikis.
by Daniel Shiffman. Create a more complex wave by adding two waves together.

<<Processing 

int xspacing = 8;   // How far apart should each horizontal location be spaced
int w;              // Width of entire wave
int maxwaves = 4;   // total # of waves to add together

float theta = 0.0f;
float[] amplitude = new float[maxwaves];   // Height of wave
float[] dx = new float[maxwaves];          // Value for incrementing X, to be calculated as a function of period and xspacing
float[] yvalues;                           // Using an array to store height values for the wave (not entirely necessary)

void setup() {
  size(200,200);
  frameRate(30);
  colorMode(RGB,255,255,255,100);
  smooth();
  w = width+16;

  for (int i = 0; i < maxwaves; i++) {
    amplitude[i] = random(10,30);
    float period = random(100,300); // How many pixels before the wave repeats
    dx[i] = (TWO_PI / period) * xspacing;
  }

  yvalues = new float[w/xspacing];
}

void draw() {
  background(0);
  calcWave();
  renderWave();
}

void calcWave() {
  // Increment theta (try different values for 'angular velocity' here
  theta += 0.02;

  // Set all height values to zero
  for (int i = 0; i < yvalues.length; i++) {
    yvalues[i] = 0.0f;
  }
 
  // Accumulate wave height values
  for (int j = 0; j < maxwaves; j++) {
    float x = theta;
    for (int i = 0; i < yvalues.length; i++) {
      // Every other wave is cosine instead of sine
      if (j % 2 == 0)  yvalues[i] += sin(x)*amplitude[j];
      else yvalues[i] += cos(x)*amplitude[j];
      x+=dx[j];
    }
  }
}

void renderWave() {
  // A simple way to draw the wave with an ellipse at each location
  noStroke();
  fill(255,50);
  ellipseMode(CENTER);
  for (int x = 0; x < yvalues.length; x++) {
    ellipse(x*xspacing,width/2+yvalues[x],16,16);
  }
}

>>

Taken from [[basic/additivewave.html|http://ejohn.org/apps/processing.js/examples/basic/additivewave.html]]
Loads a "mask" for an image to specify the transparency in different parts of the image. The two images are blended together using the mask() method of PImage. Created 29 April 2003.

<<Processing 

PImage img;
PImage maskImg;

void setup() 
{
  size(200,200);
  img = loadImage("test.jpg");
  maskImg = loadImage("mask.jpg");
  img.mask(maskImg);
}

void draw() 
{
  background((mouseX+mouseY)/1.5);
  image(img, 50, 50);
  image(img, mouseX-50, mouseY-50);
}

>>

Taken from [[basic/alphamask.html|http://ejohn.org/apps/processing.js/examples/basic/alphamask.html]]
The angle of each segment is controlled with the mouseX and mouseY position. The transformations applied to the first segment are also applied to the second segment because they are inside the same pushMatrix() and popMatrix() group.

<<Processing 

float x = 50;
float y = 100;
float angle1 = 0.0;
float angle2 = 0.0;
float segLength = 50;

void setup() {
  size(200, 200);
  smooth(); 
  strokeWeight(20.0);
  stroke(0, 100);
}

void draw() {
  background(226);
  
  angle1 = (mouseX/float(width) - 0.5) * -PI;
  angle2 = (mouseY/float(height) - 0.5) * PI;
  
  pushMatrix();
  segment(x, y, angle1); 
  segment(segLength, 0, angle2);
  popMatrix();
}

void segment(float x, float y, float a) {
  translate(x, y);
  rotate(a);
  line(0, 0, segLength, 0);
}

>>

Taken from [[basic/arm.html|http://ejohn.org/apps/processing.js/examples/basic/arm.html]]
An array is a list of data. Each piece of data in an array is identified by an index number representing its position in the array. Arrays are zero based, which means that the first element in the array is [0], the second element is [1], and so on. In this example, an array named "coswav" is created and filled with the cosine values. This data is displayed three separate ways on the screen.

<<Processing 

size(200, 200);

float[] coswave = new float[width];

for(int i=0; i<width; i++) {
  float ratio = (float)i/(float)width;
  coswave[i] = abs( cos(ratio*PI) );
}

for(int i=0; i<width; i++) {
  stroke(coswave[i]*255);
  line(i, 0, i, width/3);
}

for(int i=0; i<width; i++) {
  stroke(coswave[i]*255/4);
  line(i, width/3, i, width/3*2);
}

for(int i=0; i<width; i++) {
  stroke(255-coswave[i]*255);
  line(i, width/3*2, i, height);
}

>>

Taken from [[basic/array.html|http://ejohn.org/apps/processing.js/examples/basic/array.html]]
Demonstrates the syntax for creating a two-dimensional (2D) array. Values in a 2D array are accessed through two index values. 2D arrays are useful for storing images. In this example, each dot is colored in relation to its distance from the center of the image.

<<Processing 

float[][] distances;
float maxDistance;

size(200, 200);
background(0);
maxDistance = dist(width/2, height/2, width, height);
distances = new float[width][height];
for(int i=0; i<height; i++) {
  for(int j=0; j<width; j++) {
    float d = dist(width/2, height/2, j, i);
    distances[j][i] = d/maxDistance * 255; 
  }
}

for(int i=0; i<height; i+=2) {
  for(int j=0; j<width; j+=2) {
    stroke(distances[j][i]);
    point(j, i);
  }
}

>>

Taken from [[basic/array2d.html|http://ejohn.org/apps/processing.js/examples/basic/array2d.html]]
Demonstrates the syntax for creating an array of custom objects.

<<Processing 

int unit = 40;
int num;
Module[] mods;

void setup() 
{
  size(200, 200);
  background(176);
  noStroke();
  
  num = width/unit * width/unit;
  mods = new Module[num];
  
  for (int i=0; i<height/unit; i++) {
    for(int j=0; j<height/unit; j++) {
      int index = i*height/unit + j;
      mods[index] = new Module(j*unit, i*unit, unit/2, unit/2, random(0.05, 0.8));  
    }
  }
}

void draw() 
{
  for(int i=0; i<num; i++) {
    mods[i].update();
    mods[i].draw();
  }
}

class Module {
  float mx, my;
  int size = unit;
  float x, y = 0;
  int xdir = 1;
  int ydir = 1;
  float speed; 
  
  // Contructor (required)
  Module(float imx, float imy, float ix, float iy, float ispeed) {
    mx = imy;
    my = imx;
    x = int(ix);
    y = int(iy);
    speed = ispeed;
  }
  
  // Custom method for updating the variables
  void update() {
    x = x + (speed * xdir);
    if (x >= size || x <= 0) {
      xdir *= -1;
      x = x + (1 * xdir);
      y = y + (1 * ydir);
    }
    if (y >= size || y <= 0) {
      ydir *= -1;
      y = y + (1 * ydir);
    }
  }
  
  // Custom method for drawing the object
  void draw() {
    stroke(second()*4);
    point(mx+x-1, my+y-1);
  }
}

>>

Taken from [[basic/arrayobjects.html|http://ejohn.org/apps/processing.js/examples/basic/arrayobjects.html]]
This example presents the fastest way to load a background image into Processing. To load an image as the background, it must be the same width and height as the program.

<<Processing 

PImage bg;
int a; 

void setup() 
{
  size(200,200);
  frameRate(30);
  // The background image must be the same size as the parameters
  // into the size() method. In this program, the size of "milan_rubbish.jpg"
  // is 200 x 200 pixels.
  bg = loadImage("milan_rubbish.jpg");
}

void draw() 
{
  background(bg);

  a = (a + 1)%(width+32);
  stroke(226, 204, 0);
  line(0, a, width, a-26);
  line(0, a-6, width, a-32);
}

>>

Taken from [[basic/backgroundimage.html|http://ejohn.org/apps/processing.js/examples/basic/backgroundimage.html]]
The first two parameters for the bezier() function specify the first point in the curve and the last two parameters specify the last point. The middle parameters set the control points that define the shape of the curve.

<<Processing 

size(200, 200); 
background(0); 
stroke(255);
noFill();
smooth(); 

for(int i = 0; i < 100; i += 20) {
  bezier(90-(i/2.0), 20+i, 210, 10, 220, 150, 120-(i/8.0), 150+(i/4.0));
}

>>

Taken from [[basic/bezier.html|http://ejohn.org/apps/processing.js/examples/basic/bezier.html]]
by Rusty Robison. Brightness is the relative lightness or darkness of a color. Move the cursor vertically over each bar to alter its brightness.

<<Processing 

int barWidth = 5;
int[] brightness;

void setup() 
{
  size(200, 200);
  colorMode(HSB, 360, height, height);  
  brightness = new int[width/barWidth];
}

void draw() 
{
  int j = 0;
  for (int i = 0; i <= (width-barWidth); i += barWidth) {  
    noStroke();
    if ((mouseX > i) && (mouseX < i+barWidth)) {
      brightness[j] = mouseY;
    }
    fill(i, height, brightness[j]);
    rect(i, 0, barWidth, height);  
    j++;
  }
}

>>

Taken from [[basic/brightness.html|http://ejohn.org/apps/processing.js/examples/basic/brightness.html]]
Click on the image to give it focus and then type letters to shift the location of the image. Characters are typographic symbols such as A, d, and %. The character datatype, abbreviated as char, stores letters and symbols in the Unicode format, a coding system developed to support a variety of world languages. Characters are distinguished from other symbols by putting them between single quotes ('P'). A string is a sequence of characters. A string is noted by surrounding a group of letters with double quotes ("Processing"). Chars and strings are most often used with the keyboard methods, to display text to the screen, and to load images or files.

<<Processing 

PImage frog;
PFont fontA;
int lettersize = 90;
int xoffset;
char letter;

void setup() 
{
  size(200, 200);
  fontA = loadFont("Arial"); 
  textFont(fontA); 
  textSize(lettersize);
    
  // The String datatype must be capitalized because it is a complex datatype.
  // A String is actually a class with its own methods, some of which are
  // featured below.
  String name= "rathausFrog";
  String extension = ".jpg";
  int nameLength = name.length();
  println("The length of " + name + " is " + nameLength + ".");
  name = name.concat(extension);
  nameLength = name.length();
  println("The length of " + name + " is " + nameLength + ".");

  // The parameter for the loadImage() method must be a string
  // This line could also be written "frog = loadImage("rathausFrog.jpg");
  frog = loadImage(name);
}

void draw() 
{
  background(51); // Set background to dark gray
  
  image(frog, xoffset, 0);
  
  // Draw an X
  line(0, 0, width, height);  
  line(0, height, width, 0); 
  
  // Get the width of the letter
  int letterWidth = int(fontA.width(letter) * lettersize);
      
  // Draw the letter to the center of the screen
  text(letter, width/2-letterWidth/2, height/2);
}

void keyPressed()
{
  // The variable "key" always contains the value of the most recent key pressed.
  // If the key is an upper or lowercase letter between 'A' and 'z'
  // the image is shifted to the corresponding value of that key
  if(key >= 'A' && key <= 'z') {
    letter = char(key);
    // Scale the values to numbers between 0 and 100
    float scale = 100.0/57.0;
    int temp = int((key - 'A') * scale);
    // Set the offset for the image
    xoffset = temp;
    println(key);
  }
}

>>

Taken from [[basic/charactersstrings.html|http://ejohn.org/apps/processing.js/examples/basic/charactersstrings.html]]
The current time can be read with the second(), minute(), and hour() functions. In this example, sin() and cos() values are used to set the position of the hands. *

<<Processing 

void setup() {
  size(200, 200);
  stroke(255);
  smooth();
}
void draw() {
  background(0);
  fill(80);
  noStroke();
  // Angles for sin() and cos() start at 3 o'clock;
  // subtract HALF_PI to make them start at the top
  ellipse(100, 100, 160, 160);
  float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;
  float m = map(minute(), 0, 60, 0, TWO_PI) - HALF_PI;
  float h = map(hour() % 12, 0, 12, 0, TWO_PI) - HALF_PI;
  stroke(255);
  strokeWeight(1);
  line(100, 100, cos(s) * 72 + 100, sin(s) * 72 + 100);
  strokeWeight(2);
  line(100, 100, cos(m) * 60 + 100, sin(m) * 60 + 100);
  strokeWeight(4);
  line(100, 100, cos(h) * 50 + 100, sin(h) * 50 + 100);
}

>>

Taken from [[basic/clock.html|http://ejohn.org/apps/processing.js/examples/basic/clock.html]]
by Ira Greenberg. The primaries are red, yellow, and blue. The secondaries are green, purple, and orange. The tertiaries are  yellow-orange, red-orange, red-purple, blue-purple, blue-green, and yellow-green. Create a shade or tint of the subtractive color wheel using SHADE or TINT parameters.

<<Processing 

int segs = 12;
int steps = 6;
float rotAdjust = radians(360.0/segs/2.0);
float radius = 95.0;
float segWidth = radius/steps;
float interval = TWO_PI/segs;
int SHADE = 0;
int TINT = 1;

void setup(){
  size(200, 200);
  background(127);
  smooth();
  ellipseMode(CENTER_RADIUS);
  noStroke();
 // you can substitue TINT for SHADE argument
 createWheel(width/2, height/2, SHADE);
}

void createWheel(int x, int y, int valueShift){
  if (valueShift == SHADE){
    for (int j=0; j<steps; j++){
      color[]cols = { 
        color(255-(255/steps)*j, 255-(255/steps)*j, 0), 
        color(255-(255/steps)*j, (255/1.5)-((255/1.5)/steps)*j, 0), 
        color(255-(255/steps)*j, (255/2)-((255/2)/steps)*j, 0), 
        color(255-(255/steps)*j, (255/2.5)-((255/2.5)/steps)*j, 0), 
        color(255-(255/steps)*j, 0, 0), 
        color(255-(255/steps)*j, 0, (255/2)-((255/2)/steps)*j), 
        color(255-(255/steps)*j, 0, 255-(255/steps)*j), 
        color((255/2)-((255/2)/steps)*j, 0, 255-(255/steps)*j), 
        color(0, 0, 255-(255/steps)*j),
        color(0, 255-(255/steps)*j, (255/2.5)-((255/2.5)/steps)*j), 
        color(0, 255-(255/steps)*j, 0), 
        color((255/2)-((255/2)/steps)*j, 255-(255/steps)*j, 0) };
      for (int i=0; i< segs; i++){
        fill(cols[i]);
        arc(x, y, radius, radius, interval*i+rotAdjust, interval*(i+1)+rotAdjust);
      }
      radius -= segWidth;
    }
  } else  if (valueShift == TINT){
    for (int j=0; j<steps; j++){
      color[]cols = { 
        color((255/steps)*j, (255/steps)*j, 0), 
        color((255/steps)*j, ((255/1.5)/steps)*j, 0), 
        color((255/steps)*j, ((255/2)/steps)*j, 0), 
        color((255/steps)*j, ((255/2.5)/steps)*j, 0), 
        color((255/steps)*j, 0, 0), 
        color((255/steps)*j, 0, ((255/2)/steps)*j), 
        color((255/steps)*j, 0, (255/steps)*j), 
        color(((255/2)/steps)*j, 0, (255/steps)*j), 
        color(0, 0, (255/steps)*j),
        color(0, (255/steps)*j, ((255/2.5)/steps)*j), 
        color(0, (255/steps)*j, 0), 
        color(((255/2)/steps)*j, (255/steps)*j, 0) };
      for (int i=0; i< segs; i++){
        fill(cols[i]);
        arc(x, y, radius, radius, interval*i+rotAdjust, interval*(i+1)+rotAdjust);
      }
      radius -= segWidth;
    }
  } 
}

>>

Taken from [[basic/colorwheel.html|http://ejohn.org/apps/processing.js/examples/basic/colorwheel.html]]
An object can include several other objects. Creating such composite objects is a good way to use the principles of modularity and build higher levels of abstraction within a program.

<<Processing 

EggRing er1, er2;

void setup() 
{
  size(200, 200);
  smooth();
  er1 = new EggRing(66, 132, 0.1, 66);
  er2 = new EggRing(132, 180, 0.05, 132);
}

void draw() 
{
  background(0);
  er1.transmit();
  er2.transmit();
}

class EggRing 
{
  Egg ovoid;
  Ring circle = new Ring();
  EggRing(int x, int y, float t, float sp) {
    ovoid = new Egg(x, y, t, sp);
    circle.start(x, y - sp/2);
  }
  void transmit() {
    ovoid.wobble();
    ovoid.display();
    circle.grow();
    circle.display();
    if (circle.on == false) {
      circle.on = true;
    }
  }
}

class Egg {
  float x, y; // X-coordinate, y-coordinate
  float tilt; // Left and right angle offset
  float angle; // Used to define the tilt
  float scalar; // Height of the egg
  // Constructor
  Egg(int xpos, int ypos, float t, float s) {
    x = xpos;
    y = ypos;
    tilt = t;
    scalar = s / 100.0;
  }
  void wobble() {
    tilt = cos(angle) / 8;
    angle += 0.1;
  }
  void display() {
    noStroke();
    fill(255);
    pushMatrix();
    translate(x, y);
    rotate(tilt);
    scale(scalar);
    beginShape();
    vertex(0, -100);
    bezierVertex(25, -100, 40, -65, 40, -40);
    bezierVertex(40, -15, 25, 0, 0, 0);
    bezierVertex(-25, 0, -40, -15, -40, -40);
    bezierVertex(-40, -65, -25, -100, 0, -100);
    endShape();
    popMatrix();
  }
}

class Ring {
  float x, y; // X-coordinate, y-coordinate
  float diameter; // Diameter of the ring
  boolean on = false; // Turns the display on and off
  void start(float xpos, float ypos) {
    x = xpos;
    y = ypos;
    on = true;
    diameter = 1;
  }
  void grow() {
    if (on == true) {
      diameter += 0.5;
      if (diameter > width*2) {
        diameter = 0.0;
      }
    }
  }
  void display() {
    if (on == true) {
      noFill();
      strokeWeight(4);
      stroke(155, 153);
      ellipse(x, y, diameter, diameter);
    }
  }
}

>>

Taken from [[basic/compositeobjects.html|http://ejohn.org/apps/processing.js/examples/basic/compositeobjects.html]]
Conditions are like questions. They allow a program to decide to take one action if the answer to a question is true or to do another action if the answer to the question is false. The questions asked within a program are always logical or relational statements. For example, if the variable 'i' is equal to zero then draw a line.

<<Processing 

size(200, 200);
background(0);

for(int i=10; i<width; i+=10) {
  // If 'i' divides by 20 with no remainder draw the first line
  // else draw the second line
  if(i%20 == 0) {
    stroke(153);
    line(i, 40, i, height/2);
  } else {
    stroke(102);
    line(i, 20, i, 180); 
  }
}

>>

Taken from [[basic/conditionals1.html|http://ejohn.org/apps/processing.js/examples/basic/conditionals1.html]]
We extend the language of conditionals by adding the keyword "else". This allows conditionals to ask two or more sequential questions, each with a different action.

<<Processing 

size(200, 200);
background(0);

for(int i=2; i<width-2; i+=2) {
  // If 'i' divides by 20 with no remainder 
  // draw the first line else draw the second line
  if(i%20 == 0) {
    stroke(255);
    line(i, 40, i, height/2);
  } else if (i%10 == 0) {
    stroke(153);
    line(i, 20, i, 180); 
  } else {
    stroke(102);
    line(i, height/2, i, height-40);
  }
}

>>

Taken from [[basic/conditionals2.html|http://ejohn.org/apps/processing.js/examples/basic/conditionals2.html]]
Move the mouse across the screen to move the circle. The program constrains the circle to its box.

<<Processing 

float mx;
float my;
float easing = 0.05;
float esize = 25.0;
int box = 30;

void setup() 
{
  size(200, 200);
  noStroke(); 
  smooth();
  ellipseMode(CENTER_RADIUS);  
}

void draw() 
{ 
  background(51);
  
  if(abs(mouseX - mx) > 0.1) {
    mx = mx + (mouseX - mx) * easing;
  }
  if(abs(mouseY - my) > 0.1) {
    my = my + (mouseY- my) * easing;
  }
  
  float distance = esize * 2;
  mx = constrain(mx, box+distance, width-box-distance);
  my = constrain(my, box+distance, height-box-distance);
  fill(76);
  rect(box+esize, box+esize, box*3, box*3);
  fill(255);  
  ellipse(mx, my, esize, esize);
}

>>

Taken from [[basic/constrain.html|http://ejohn.org/apps/processing.js/examples/basic/constrain.html]]
All shapes drawn to the screen have a position that is specified as a coordinate. All coordinates are measured as the distance from the origin in units of pixels. The origin [0, 0] is the coordinate is in the upper left of the window and the coordinate in the lower right is [width-1, height-1].

<<Processing 

// Sets the screen to be 200, 200, so the width of the window is 200 pixels
// and the height of the window is 200 pixels
size(200, 200);
background(0);
noFill();
stroke(255);

// The two parameters of the point() method each specify coordinates.
// This call to point() draws at the position [100, 100]
point(width/2, height/2);

// Draws to the position [100, 50]
point(width/2, height/4); 

// It is also possible to specify a point with any parameter, 
// but only coordinates on the screen are visible
point(60, 30);
point(60, 134);
point(160, 50);
point(280, -800);
point(201, 100);

// Coordinates are used for drawing all shapes, not just points.
// Parameters for different methods are used for different purposes.
// For example, the first two parameters to line() specify the coordinates of the 
// first point and the second two parameters specify the second point
stroke(204);
line(0, 73, width, 73);

// The first two parameters to rect() are coordinates
// and the second two are the width and height
rect(110, 55, 40, 36);

>>

Taken from [[basic/coordinates.html|http://ejohn.org/apps/processing.js/examples/basic/coordinates.html]]
The createGraphics() function creates an object from the PGraphics class (PGraphics is the main graphics and rendering context for Processing). The beginDraw() method is necessary to prepare for drawing and endDraw() is necessary to finish. Use this class if you need to draw into an off-screen graphics buffer or to maintain two contexts with different properties.

<<Processing 

PGraphics pg;

void setup() {
  size(200, 200);
  pg = createGraphics(80, 80, P3D);
}

void draw() {
  fill(0, 12);
  rect(0, 0, width, height);
  fill(255);
  noStroke();
  ellipse(mouseX, mouseY, 60, 60);
  
  pg.beginDraw();
  pg.background(102);
  pg.noFill();
  pg.stroke(255);
  pg.ellipse(mouseX-60, mouseY-60, 60, 60);
  pg.endDraw();
  
  image(pg, 60, 60); 
}

>>

Taken from [[basic/creategraphics.html|http://ejohn.org/apps/processing.js/examples/basic/creategraphics.html]]
The createImage() function provides a fresh buffer of pixels to play with. This example creates an image gradient.

<<Processing 

PImage img;

void setup() 
{
  size(200, 200);  
  img = createImage(120, 120, RGB);
  for(int i=0; i < img.pixels.length; i++) {
    img.pixels[i] = color(0, 90, 102, i%img.width * 2); 
  }
}

void draw() 
{
  background(204);
  image(img, 33, 33);
  image(img, mouseX-60, mouseY-60);
}

>>

Taken from [[basic/createimage.html|http://ejohn.org/apps/processing.js/examples/basic/createimage.html]]
Creating variables for colors that may be referred to in the program by their name, rather than a number.

<<Processing 

size(200, 200);
noStroke();

color inside = color(204, 102, 0);
color middle = color(204, 153, 0);
color outside = color(153, 51, 0);

// These statements are equivalent to the statements above.
// Programmers may use the format they prefer.
//color inside = #CC6600;
//color middle = #CC9900;
//color outside = #993300;

fill(outside);
rect(0, 0, 200, 200);
fill(middle);
rect(40, 60, 120, 120);
fill(inside);
rect(60, 90, 80, 80);

>>

Taken from [[basic/creating.html|http://ejohn.org/apps/processing.js/examples/basic/creating.html]]
It is sometimes beneficial to convert a value from one type of data to another. Each of the conversion functions converts its parameter to an equivalent representation within its datatype. The conversion functions include int(), float(), char(), byte(), and others.

<<Processing 

size(200, 200);
background(51);
noStroke();

char c;    // Chars are used for storing typographic symbols
float f;   // Floats are decimal numbers
int i;     // Ints are values between 2,147,483,647 and -2147483648
byte b;    // Bytes are values between -128 and 128

c = 'A';
f = float(c);     // Sets f = 65.0
i = int(f * 1.4); // Sets i to 91
b = byte(c / 2);  // Sets b to 32

rect(f, 0, 40, 66);
fill(204);
rect(i, 67, 40, 66);
fill(255);
rect(b, 134, 40, 66);

>>

Taken from [[basic/datatypeconversion.html|http://ejohn.org/apps/processing.js/examples/basic/datatypeconversion.html]]
Images can be displayed to the screen at their actual size or any other size.

<<Processing 

size(200, 200);
PImage a;  // Declare variable "a" of type PImage
a = loadImage("arch.jpg"); // Load the images into the program
image(a, 0, 0); // Displays the image from point (0,0)
image(a, width/2, 0, a.width/2, a.height/2);

>>

Taken from [[basic/displaying.html|http://ejohn.org/apps/processing.js/examples/basic/displaying.html]]
Move the mouse across the image to obscure and reveal the matrix. Measures the distance from the mouse to each square and sets the size proportionally.

<<Processing 

float max_distance;

void setup() {
  size(200, 200); 
  smooth();
  noStroke();
  max_distance = dist(0, 0, width, height);
}

void draw() 
{
  background(51);

  for(int i = 0; i <= width; i += 20) {
    for(int j = 0; j <= width; j += 20) {
      float size = dist(mouseX, mouseY, i, j);
      size = size/max_distance * 66;
      //opera.postError(i, j, size);
      ellipse(i, j, size, size);
    }
  }
}

>>

Taken from [[basic/distance2d.html|http://ejohn.org/apps/processing.js/examples/basic/distance2d.html]]
by Ira Greenberg. Using 2 random() calls the and point() function to create an irregular sawtooth line.

<<Processing 

size(200, 200);
background(0);
int totalPts = 300;
float steps = totalPts+1;
stroke(255);
float rand = 0;

for  (int i=1; i< steps; i++){
  point( (width/steps) * i, (height/2) + random(-rand, rand) );
  rand += random(-5, 5);
}

>>

Taken from [[basic/doublerandom.html|http://ejohn.org/apps/processing.js/examples/basic/doublerandom.html]]
Move the mouse across the screen and the symbol will follow. Between drawing each frame of the animation, the program calculates the difference between the position of the symbol and the cursor. If the distance is larger than 1 pixel, the symbol moves half of the distance from its current position toward the cursor.

<<Processing 

float x;
float y;
float targetX, targetY;
float easing = 0.05;

void setup() 
{
  size(200, 200); 
  smooth();
  noStroke();  
}

void draw() 
{ 
  background( 51 );
  
  targetX = mouseX;
  float dx = mouseX - x;
  if(abs(dx) > 1) {
    x += dx * easing;
  }
  
  targetY = mouseY;
  float dy = mouseY - y;
  if(abs(dy) > 1) {
    y += dy * easing;
  }
  
  ellipse(x, y, 33, 33);
}

>>

Taken from [[basic/easing.html|http://ejohn.org/apps/processing.js/examples/basic/easing.html]]
Embedding "for" structures allows repetition in two dimensions.

<<Processing 

float box_size = 11; 
float box_space = 12; 
int margin = 7; 
 
size(200, 200); 
background(0); 
noStroke(); 
 
// Draw gray boxes 
 
for(int i = margin; i < width-margin; i += box_space) { 
  for(int j = margin; j < height-margin; j += box_space) { 
    fill(255 - box_size*10); 
    rect(j, i, box_size, box_size); 
  } 
  box_size = box_size - 0.6; 
}

>>

Taken from [[basic/embeddediteration.html|http://ejohn.org/apps/processing.js/examples/basic/embeddediteration.html]]
Click on the left button to open a different URL in the same window (Only works online). Click on the right button to open a URL in a new browser window. Created 21 June 2003.

<<Processing 

boolean overLeftButton = false;
boolean overRightButton = false;

void setup()
{
  size(200, 200);
}

void draw()
{
  background(204);
  
  // Left buttom
  if(overLeftButton == true) {
    fill(255);
  } else {
    noFill();
  }
  rect(20, 60, 75, 75);
  rect(50, 90, 15, 15);
  
  // Right button
  if(overRightButton == true) {
    fill(255);
  } else {
    noFill();
  }
  rect(105, 60, 75, 75);
  line(135, 105, 155, 85);
  line(140, 85, 155, 85);
  line(155, 85, 155, 100);
}

void mousePressed() 
{
  if(overLeftButton) { 
    link("http://www.processing.org");
  } else if (overRightButton) {
    link("http://www.processing.org", "_new");
  }
}

void mouseMoved() { 
  checkButtons(); 
}
  
void mouseDragged() {
  checkButtons(); 
}

void checkButtons() {
  if(mouseX > 20 && mouseX < 95 &&
     mouseY > 60 && mouseY <135) {
    overLeftButton = true;   
  }  else if (mouseX > 105 && mouseX < 180 &&
     mouseY > 60 && mouseY <135) {
    overRightButton = true; 
  } else {
    overLeftButton = overRightButton = false;
  }

}

>>

Taken from [[basic/embeddedlinks.html|http://ejohn.org/apps/processing.js/examples/basic/embeddedlinks.html]]
The draw_target() function makes it easy to draw many distinct targets. Each call to draw_target() specifies the position, size, and number of rings for each target.

<<Processing 

void setup() 
{
  size(200, 200);
  background(51);
  noStroke();
  smooth();
  noLoop();
}

void draw() 
{
  draw_target(68, 34, 200, 10);
  draw_target(152, 16, 100, 3);
  draw_target(100, 144, 80, 5);
}

void draw_target(int xloc, int yloc, int size, int num) 
{
  float grayvalues = 255/num;
  float steps = size/num;
  for(int i=0; i<num; i++) {
    fill(i*grayvalues);
    ellipse(xloc, yloc, size-i*steps, size-i*steps);
  }
}

>>

Taken from [[basic/functions.html|http://ejohn.org/apps/processing.js/examples/basic/functions.html]]
by Daniel Shiffman. Graphics the following equation: sin(n*cos(r) + 5*theta) where n is a function of horizontal mouse location.

<<Processing 

void setup() {
  size(50,50);
  frameRate(30);
}

void draw() {
  loadPixels();
  float n = (mouseX * 10.0) / width;
  float w = 16.0;         // 2D space width
  float h = 16.0;         // 2D space height
  float dx = w / width;    // Increment x this amount per pixel
  float dy = h / height;   // Increment y this amount per pixel
  float x = -w/2;          // Start x at -1 * width / 2
  for (int i = 0; i < width; i++) {
    float y = -h/2;        // Start y at -1 * height / 2
    for (int j = 0; j < height; j++) {
      float r = sqrt((x*x) + (y*y));    // Convert cartesian to polar
      float theta = atan2(y,x);         // Convert cartesian to polar
      // Compute 2D polar coordinate function
      float val = sin(n*cos(r) + 5 * theta);           // Results in a value between -1 and 1
      //float val = cos(r);                            // Another simple function
      //float val = sin(theta);                        // Another simple function
      // Map resulting vale to grayscale value
      pixels[i+j*width] = color((val + 1.0) * 255.0/2.0);     // Scale to between 0 and 255
      y += dy;                // Increment y
    }
    x += dx;                  // Increment x
  }
  updatePixels();
}

>>

Taken from [[basic/graphing2dequation.html|http://ejohn.org/apps/processing.js/examples/basic/graphing2dequation.html]]
Hue is the color reflected from or transmitted through an object and is typically referred to as the name of the color (red, blue, yellow, etc.) Move the cursor vertically over each bar to alter its hue.

<<Processing 

int barWidth = 5;
int[] hue;

void setup() 
{
  size(400, 400);
  colorMode(HSB, 360, height, height);  
  hue = new int[width/barWidth];
  noStroke();
}

void draw() 
{
  int j = 0;
  for (int i=0; i<=(width-barWidth); i+=barWidth) {  
    if ((mouseX > i) && (mouseX < i+barWidth)) {
      hue[j] = mouseY;
    }
    fill(hue[j], height/1.2, height/1.2);
    rect(i, 0, barWidth, height);  
    j++;
  }
}

>>

Taken from [[basic/hue.html|http://ejohn.org/apps/processing.js/examples/basic/hue.html]]
Writing "a++" is equivalent to "a = a + 1". Writing "a--" is equivalent to "a = a - 1".

<<Processing 

int a;
int b;
boolean direction;

void setup()
{
  size(200, 200);
  colorMode(RGB, width);
  a = 0;
  b = width;
  direction = true;
  frameRate(30);
}

void draw()
{
  a++;
  if(a > width) {
    a = 0;
    direction = !direction;
  }
  if(direction == true){
    stroke(a);
  } else {
    stroke(width-a);
  }
  line(a, 0, a, height/2);

  b--;
  if(b < 0) {
    b = width;
  }
  if(direction == true) {
    stroke(width-b);
  } else {
    stroke(b);
  }
  line(b, height/2+1, b, height);
}

>>

Taken from [[basic/incrementdecrement.html|http://ejohn.org/apps/processing.js/examples/basic/incrementdecrement.html]]
A class can be defined using another class as a foundation. In object-oriented programming terminology, one class can inherit fi elds and methods from another. An object that inherits from another is called a subclass, and the object it inherits from is called a superclass. A subclass extends the superclass.

<<Processing 

SpinSpots spots;
SpinArm arm;

void setup() 
{
  size(200, 200);
  smooth();
  arm = new SpinArm(width/2, height/2, 0.01);
  spots = new SpinSpots(width/2, height/2, -0.02, 33.0);
}

void draw() 
{
  background(204);
  arm.update();
  arm.display();
  spots.update();
  spots.display();
}

class Spin 
{
  float x, y, speed;
  float angle = 0.0;
  Spin(float xpos, float ypos, float s) {
    x = xpos;
    y = ypos;
    speed = s;
  }
  void update() {
    angle += speed;
  }
}

class SpinArm extends Spin 
{
  SpinArm(float x, float y, float s) {
    super(x, y, s);
  }
  void display() {
    strokeWeight(1);
    stroke(0);
    pushMatrix();
    translate(x, y);
    angle += speed;
    rotate(angle);
    line(0, 0, 66, 0);
    popMatrix();
  }
}

class SpinSpots extends Spin 
{
  float dim;
  SpinSpots(float x, float y, float s, float d) {
    super(x, y, s);
    dim = d;
  }
  void display() {
    noStroke();
    pushMatrix();
    translate(x, y);
    angle += speed;
    rotate(angle);
    ellipse(-dim/2, 0, dim, dim);
    ellipse(dim/2, 0, dim, dim);
    popMatrix();
  }
}

>>

Taken from [[basic/inheritance.html|http://ejohn.org/apps/processing.js/examples/basic/inheritance.html]]
Integers and floats are two different kinds of numerical data. An integer (more commonly called an int) is a number without a decimal point. A float is a floating-point number, which means it is a number that has a decimal place. Floats are used when more precision is needed.

<<Processing 

int a = 0;      // Create a variable "a" of the datatype "int"
float b = 0.0;  // Create a variable "b" of the datatype "float"

void setup()
{
  size(200, 200);
  stroke(255);
  frameRate(30);
}

void draw()
{
  background(51);
  
  a = a + 1;
  b = b + 0.2; 
  line(a, 0, a, height/2);
  line(b, height/2, b, height);
  
  if(a > width) {
    a = 0;
  }
  if(b > width) {
    b = 0;
  }
}

>>

Taken from [[basic/integersfloats.html|http://ejohn.org/apps/processing.js/examples/basic/integersfloats.html]]
Iteration with a "for" structure constructs repetitive forms.

<<Processing 

int k;
int xpos1 = 100; 
int xpos2 = 118; 
int count = 0; 
int timey = 0;
int num = 12;

size(200, 200);
background(102);
noStroke();
 
// Draw gray bars 
fill(255);
k=60;
for(int i=0; i < num/3; i++) {
  rect(25, k, 155, 5);
  k+=10;
}

// Black bars
fill(51);
k = 40;
for(int i=0; i < num; i++) {
  rect(105, k, 30, 5);
  k += 10;
}
k = 15;
for(int i = 0; i < num; i++) {
  rect(125, k, 30, 5);
  k +=10;
}
  
// Thin lines
k = 42;
fill(0);
for(int i=0; i < num-1; i++) {
  rect(36, k, 20, 1);
  k+=10;
}

>>

Taken from [[basic/iteration.html|http://ejohn.org/apps/processing.js/examples/basic/iteration.html]]
Click on the image to give it focus and press the letter keys to create forms in time and space. Each key has a unique identifying number called it's ASCII value. These numbers can be used to position shapes in space.

<<Processing 

int numChars = 26;
color[] colors = new color[numChars];
int keyIndex;
float keyScale;
int rectWidth;

    
void setup()
{
  size(200, 200);
  noStroke();
  background(0);
  keyScale = 200/numChars-1.0;
  rectWidth = width/4;
}

void draw()
{ 
  if(keyPressed) {
    if(key >= 'A' && key <= 'z') {
      if(key <= 'Z') {
        keyIndex = key-'A';
      } else {
        keyIndex = key-'a';
      }
      fill(millis()%255);
      float beginRect = rectWidth/2 + keyIndex*keyScale-rectWidth/2;
      rect(beginRect, 0.0, rectWidth, height);
    }
  }
}

>>

Taken from [[basic/keyboard.html|http://ejohn.org/apps/processing.js/examples/basic/keyboard.html]]
Modified from code by Martin. Original 'Color Typewriter' concept by John Maeda. Click on the window to give it focus and press the letter keys to type colors. The keyboard function keyPressed() is called whenever a key is pressed. keyReleased() is another keyboard function that is called when a key is released.

<<Processing 

int max_height = 20;
int min_height = 10;
int letter_height = max_height; // Height of the letters
int letter_width = 10;          // Width of the letter

int x = -letter_width;          // X position of the letters
int y = 0;                      // Y position of the letters

boolean newletter;              

int numChars = 26;      // There are 26 characters in the alphabet
color[] colors = new color[numChars];

void setup()
{
  size(200, 200);
  noStroke();
  colorMode(RGB, numChars);
  background(numChars/2);
  // Set a gray value for each key
  for(int i=0; i<numChars; i++) {
    colors[i] = color(i, i, i);    
  }
}

void draw()
{
  if(newletter == true) {
    // Draw the "letter"
    int y_pos;
    if (letter_height == max_height) {
      y_pos = y;
      rect( x, y_pos, letter_width, letter_height );
    } else {
      y_pos = y + min_height;
      rect( x, y_pos, letter_width, letter_height );
      fill(numChars/2);
      rect( x, y_pos-min_height, letter_width, letter_height );
    }
    newletter = false;
  }
}

void keyPressed()
{
  // if the key is between 'A'(65) and 'z'(122)
  if( key >= 'A' && key <= 'z') {
    int keyIndex;
    if(key <= 'Z') {
      keyIndex = key-'A';
      letter_height = max_height;
      fill(colors[key-'A']);
    } else {
      keyIndex = key-'a';
      letter_height = min_height;
      fill(colors[key-'a']);
    }
  } else {
    fill(0);
    letter_height = 10;
  }

  newletter = true;

  // Update the "letter" position
  x = ( x + letter_width ); 

  // Wrap horizontally
  if (x > width - letter_width) {
    x = 0;
    y+= max_height;
  }

  // Wrap vertically
  if( y > height - letter_height) {
    y = 0;      // reset y to 0
  }
}

>>

Taken from [[basic/keyboardfunctions.html|http://ejohn.org/apps/processing.js/examples/basic/keyboardfunctions.html]]
Drawing letters to the screen in Processing uses a technology developed in the mid 1990s at the Visual Language Workshop at the MIT Media Laboratory. It is a closed system, but we have supplied a number of fonts located in the "font" directory in the main "processing" directory. We expect to change the Processing font technology in the future.

<<Processing 

size(200, 200);
background(0);

// Load the font. Fonts are located within the 
// main Processing directory/folder and they
// must be placed within the data directory
// of your sketch for them to load
PFont fontA = loadFont("Courier New");
textFont(fontA, 36);
textAlign(CENTER);

// Set the gray value of the letters
fill(255);

// Set the left and top margin
int margin = 6;
int gap = 30;
translate(margin*1.5, margin*2);

// Create a matrix of letterforms
int counter = 0;
for(int i=0; i<margin; i++) {
  for(int j=0; j<margin; j++) {
    char letter;
    
    // Select the letter
    int count = 65+(i*margin)+j;
    if(count <= 90) {
      letter = char(65+counter);
      if(letter == 'A' || letter == 'E' || letter == 'I' || 
         letter == 'O' || letter == 'U') {
           fill(204, 204, 0);
      } else {
        fill(255);
      }
    } else {
      fill(153);
      letter = char(48+counter);
    }
 
    // Draw the letter to the screen
    text(letter, 15+j*gap, 20+i*gap);
 
    // Increment the counter
    counter++;
    if(counter >= 26) {
      counter = 0;
    }
  }
}

>>

Taken from [[basic/letters.html|http://ejohn.org/apps/processing.js/examples/basic/letters.html]]
by Ira Greenberg. Using the convenient red(), green() and blue() component functions, generate some linear gradients.

<<Processing 

// constants
int Y_AXIS = 1;
int X_AXIS = 2;

void setup(){
  size(200, 200);

  // create some gradients
  // background
  color b1 = color(190, 190, 190);
  color b2 = color(20, 20, 20);
  //setGradient(0, 0, width, height, b1, b2, Y_AXIS);
  //center squares
  color c1 = color(255, 120, 0);
  color c2 = color(10, 45, 255);
  color c3 = color(10, 255, 15);
  color c4 = color(125, 2, 140);
  color c5 = color(255, 255, 0);
  color c6 = color(25, 255, 200);
  setGradient(25, 25, 75, 75, c1, c2, Y_AXIS);
  setGradient(100, 25, 75, 75, c3, c4, X_AXIS);
  setGradient(25, 100, 75, 75, c2, c5, X_AXIS);
  setGradient(100, 100, 75, 75, c4, c6, Y_AXIS);
}

void setGradient(int x, int y, float w, float h, color c1, color c2, int axis ){
  // calculate differences between color components 
  float deltaR = red(c2)-red(c1);
  float deltaG = green(c2)-green(c1);
  float deltaB = blue(c2)-blue(c1);

  // choose axis
  if(axis == Y_AXIS){
    /*nested for loops set pixels
     in a basic table structure */
    // column
    for (int i=x; i<=(x+w); i++){
      // row
      for (int j = y; j<=(y+h); j++){
        color c = color(
        (red(c1)+(j-y)*(deltaR/h)),
        (green(c1)+(j-y)*(deltaG/h)),
        (blue(c1)+(j-y)*(deltaB/h)) 
          );
        set(i, j, c);
      }
    }  
  }  
  else if(axis == X_AXIS){
    // column 
    for (int i=y; i<=(y+h); i++){
      // row
      for (int j = x; j<=(x+w); j++){
        color c = color(
        (red(c1)+(j-x)*(deltaR/h)),
        (green(c1)+(j-x)*(deltaG/h)),
        (blue(c1)+(j-x)*(deltaB/h)) 
          );
        set(j, i, c);
      }
    }  
  }
}

>>

Taken from [[basic/lineargradient.html|http://ejohn.org/apps/processing.js/examples/basic/lineargradient.html]]
The logical operators for AND (&&) and OR (||) are used to combine simple relational statements into more complex expressions. The NOT (!) operator is used to negate a boolean statement.

<<Processing 

size(200, 200);
background(126);

boolean op = false;

for(int i=5; i<=195; i+=5) {
  // Logical AND
  stroke(0);
  if((i > 35) && (i < 100)) {
    line(5, i, 95, i);
    op = false;
  }
  
  // Logical OR
  stroke(76);
  if((i <= 35) || (i >= 100)) {
    line(105, i, 195, i);
    op = true;
  }
  
  // Testing if a boolean value is "true"
  // The expression "if(op)" is equivalent to "if(op == true)"
  if(op) {
    stroke(0);
    point(width/2, i);
  }
    
  // Testing if a boolean value is "false"
  // The expression "if(!op)" is equivalent to "if(op == false)"
  if(!op) {
    stroke(255);
    point(width/4, i);
  }
}

>>

Taken from [[basic/logicaloperators.html|http://ejohn.org/apps/processing.js/examples/basic/logicaloperators.html]]
The loop() function causes draw() to execute continuously. If noLoop is called in setup() the draw() is only executed once. In this example click the mouse to execute loop(), which will cause the draw() the execute continuously.

<<Processing 

// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set stroke color to white
  noLoop();
}

float y = 100;

// The statements in draw() are run until the 
// program is stopped. Each statement is run in 
// sequence and after the last line is read, the first 
// line is run again.
void draw() 
{ 
  background(0);   // Set the background to black
  line(0, y, width, y);  
  
  y = y - 1; 
  if (y < 0) { 
    y = height; 
  } 
} 

void mousePressed() 
{
  loop();
}

>>

Taken from [[basic/loop.html|http://ejohn.org/apps/processing.js/examples/basic/loop.html]]
A millisecond is 1/1000 of a second. Processing keeps track of the number of milliseconds a program has run. By modifying this number with the modulo(%) operator, different patterns in time are created.

<<Processing 

float scale;

void setup()
{
  size(200, 200);
  noStroke();
  scale = width/10;
}

void draw()
{ 
  for(int i=0; i<scale; i++) {
    colorMode(RGB, (i+1) * scale * 10);
    fill(millis()%((i+1) * scale * 10) );
    rect(i*scale, 0, scale, height);
  }
}

>>

Taken from [[basic/milliseconds.html|http://ejohn.org/apps/processing.js/examples/basic/milliseconds.html]]
The modulo operator (%) returns the remainder of a number divided by another. As in this example, it is often used to keep numerical values within a set range. Created 12 January 2003.

<<Processing 

int num = 20;
float c;

void setup()
{
  size(200,200);
  fill(255);
  frameRate(30);
}

void draw() 
{ 
  background(0);
  c+=0.1;
  for(int i=1; i<height/num; i++) { 
    float x = (c%i)*i*i;
    stroke(102);
    line(0, i*num, x, i*num);
    noStroke();
    rect(x, i*num-num/2, 8, num);
  } 
}

>>

Taken from [[basic/modulo.html|http://ejohn.org/apps/processing.js/examples/basic/modulo.html]]
Move the mouse left and right to shift the balance. The "mouseX" variable is used to control both the size and color of the rectangles.

<<Processing 

int gx = 15;
int gy = 35;
float leftColor = 0.0;
float rightColor = 0.0;

void setup() 
{
  size(200, 200);
  colorMode(RGB, 1.0);
  noStroke();
}

void draw() 
{
  background(0.0);
  update(mouseX); 
  fill(0.0, leftColor + 0.4, leftColor + 0.6); 
  rect(width/4-gx, width/2-gx, gx*2, gx*2); 
  fill(0.0, rightColor + 0.2, rightColor + 0.4); 
  rect(width/1.33-gy, width/2-gy, gy*2, gy*2);
}

void update(int x) 
{
  leftColor = -0.002 * x/2 + 0.06;
  rightColor =  0.002 * x/2 + 0.06;
	
  gx = x/2;
  gy = 100-x/2;

  if (gx < 10) {
    gx = 10;
  } else if (gx > 90) {
    gx = 90;
  }

  if (gy > 90) {
    gy = 90;
  } else if (gy < 10) {
    gy = 10;
  }
}

>>

Taken from [[basic/mouse1d.html|http://ejohn.org/apps/processing.js/examples/basic/mouse1d.html]]
Moving the mouse changes the position and size of each box.

<<Processing 

void setup() 
{
  size(200, 200); 
  noStroke();
  colorMode(RGB, 255, 255, 255, 100);
  rectMode(CENTER);
}

void draw() 
{   
  background(51); 
  fill(255, 80);
  rect(mouseX, height/2, mouseY/2+10, mouseY/2+10);
  fill(255, 80);
  rect(width-mouseX, height/2, ((height-mouseY)/2)+10, ((height-mouseY)/2)+10);
}

>>

Taken from [[basic/mouse2d.html|http://ejohn.org/apps/processing.js/examples/basic/mouse2d.html]]
Click on the box and drag it across the screen.

<<Processing 

float bx;
float by;
int bs = 20;
boolean bover = false;
boolean locked = false;
float bdifx = 0.0; 
float bdify = 0.0; 


void setup() 
{
  size(200, 200);
  bx = width/2.0;
  by = height/2.0;
  rectMode(CENTER_RADIUS);  
}

void draw() 
{ 
  background(0);
  
  // Test if the cursor is over the box 
  if (mouseX > bx-bs && mouseX < bx+bs && 
      mouseY > by-bs && mouseY < by+bs) {
    bover = true;  
    if(!locked) { 
      stroke(255); 
      fill(153);
    } 
  } else {
    stroke(153);
    fill(153);
    bover = false;
  }
  
  // Draw the box
  rect(bx, by, bs, bs);
}

void mousePressed() {
  if(bover) { 
    locked = true; 
    fill(255, 255, 255);
  } else {
    locked = false;
  }
  bdifx = mouseX-bx; 
  bdify = mouseY-by; 

}

void mouseDragged() {
  if(locked) {
    bx = mouseX-bdifx; 
    by = mouseY-bdify; 
  }
}

void mouseReleased() {
  locked = false;
}

>>

Taken from [[basic/mousefunctions.html|http://ejohn.org/apps/processing.js/examples/basic/mousefunctions.html]]
Move the mouse to position the shape. Press the mouse button to invert the color.

<<Processing 

void setup() {
  size(200, 200);
  fill(126);
  background(102);
}

void draw() {
  if(mousePressed) {
    stroke(255);
  } else {
    stroke(0);
  }
  line(mouseX-66, mouseY, mouseX+66, mouseY);
  line(mouseX, mouseY-66, mouseX, mouseY+66); 
}

>>

Taken from [[basic/mousepress.html|http://ejohn.org/apps/processing.js/examples/basic/mousepress.html]]
Move and click the mouse to generate signals. The top row is the signal from "mouseX", the middle row is the signal from "mouseY", and the bottom row is the signal from "mousePressed".

<<Processing 

int[] xvals;
int[] yvals;
int[] bvals;

void setup() 
{
  size(200, 200);
  xvals = new int[width];
  yvals = new int[width];
  bvals = new int[width];
}

int arrayindex = 0;

void draw()
{
  background(102);
  
  for(int i=1; i<width; i++) { 
    xvals[i-1] = xvals[i]; 
    yvals[i-1] = yvals[i];
    bvals[i-1] = bvals[i];
  } 
  // Add the new values to the end of the array 
  xvals[width-1] = mouseX; 
  yvals[width-1] = mouseY;
  if(mousePressed) {
    bvals[width-1] = 0;
  } else {
    bvals[width-1] = 255;
  }
  
  fill(255);
  noStroke();
  rect(0, height/3, width, height/3+1);

  for(int i=1; i<width; i++) {
    stroke(255);
    point(i, xvals[i]/3);
    stroke(0);
    point(i, height/3+yvals[i]/3);
    stroke(255);
    line(i, 2*height/3+bvals[i]/3, i, (2*height/3+bvals[i-1]/3));
  }
}

>>

Taken from [[basic/mousesignals.html|http://ejohn.org/apps/processing.js/examples/basic/mousesignals.html]]
A class can have multiple constructors that assign the fields in different ways. Sometimes it's beneficial to specify every aspect of an objectÕs data by assigning parameters to the fields, but other times it might be appropriate to define only one or a few.

<<Processing 

Spot sp1, sp2;
void setup() 
{
  size(200, 200);
  background(204);
  smooth();
  noLoop();
  // Run the constructor without parameters
  sp1 = new Spot();
  // Run the constructor with three parameters
  sp2 = new Spot(122, 100, 40);
}

void draw() {
  sp1.display();
  sp2.display();
}

class Spot {
  float x, y, radius;
  // First version of the Spot constructor;
  // the fields are assigned default values
  Spot() {
    x = 66;
    y = 100;
    radius = 16;
  }
  // Second version of the Spot constructor;
  // the fields are assigned with parameters
  Spot(float xpos, float ypos, float r) {
    x = xpos;
    y = ypos;
    radius = r;
  }
  void display() {
    ellipse(x, y, radius*2, radius*2);
  }
}

>>

Taken from [[basic/multipleconstructors.html|http://ejohn.org/apps/processing.js/examples/basic/multipleconstructors.html]]
By Ira Greenberg Draw a neighborhood of houses using Door, Window, Roof and House classes. Good example of class composition, with component Door, Window, Roof class references encapsulated within House class. This arrangement allows House class to handle placement and sizing of its components, while still allowing user customization of the individual components.

<<Processing 

void setup(){
  size(200, 200);
  background(190);
  smooth();
  // Ground plane
  int groundHeight = 10;
  fill(0);
  rect(0, height-groundHeight, width, groundHeight);
  fill(255);
  
  // Center the houses
  translate(12, 0);

  // Houses
  Door door1 = new Door(20, 40);
  Window window1 = new Window(50, 62, false, Window.DOUBLE);
  Roof roof1 = new Roof(Roof.DOME);
  House house1 = new House(75, 75, door1, window1, roof1, House.MIDDLE_DOOR);
  house1.drawHouse(0, height-groundHeight-house1.h, true);

  Door door2 = new Door(20, 40);
  Window window2 = new Window(50, 62, true, Window.QUAD);
  Roof roof2 = new Roof(Roof.GAMBREL);
  House house2 = new House(100, 60, door2, window2, roof2, House.LEFT_DOOR);
  house2.drawHouse(house1.x + house1.w, height-groundHeight-house2.h, true);
}

class Door{
  //door properties
  int x;
  int y;
  int w;
  int h;

  // for knob
  int knobLoc = 1;
  //constants
  final static int RT = 0;
  final static int LFT = 1;

  // constructor
  Door(int w, int h){
    this.w = w;
    this.h = h;
  }

  // draw the door
  void drawDoor(int x, int y) {
    rect(x, y, w, h);
    int knobsize = w/10;
    if (knobLoc == 0){
      //right side
      ellipse(x+w-knobsize, y+h/2, knobsize, knobsize);
    }
    else {
      //left side
      ellipse(x+knobsize, y+h/2, knobsize, knobsize);
    }
  }

  // set knob position
  void setKnob(int knobLoc){
    this. knobLoc = knobLoc;
  }
}

class Window{
  //window properties
  int x;
  int y;
  int w;
  int h;

  // customized features
  boolean hasSash = false;

  // single, double, quad pane
  int style = 0;
  //constants
  final static int SINGLE = 0;
  final static int DOUBLE = 1;
  final static int QUAD = 2;

  // constructor 1
  Window(int w, int h){
    this.w = w;
    this.h = h;
  }
  // constructor 2
  Window(int w, int h, int style){
    this.w = w;
    this.h = h;
    this.style = style;
  }
  // constructor 3
  Window(int w, int h, boolean hasSash, int style){
    this.w = w;
    this.h = h;
    this.hasSash = hasSash;
    this.style = style;
  }

  // draw the window
  void drawWindow(int x, int y) {
    //local variables
    int margin = 0;
    int winHt = 0;
    int winWdth = 0;

    if (hasSash){
      margin = w/15;
    }

    switch(style){
    case 0:
      //outer window (sash)
      rect(x, y, w, h);
      //inner window
      rect(x+margin, y+margin, w-margin*2, h-margin*2);
      break;
    case 1:
      winHt = (h-margin*3)/2;
      //outer window (sash)
      rect(x, y, w, h);
      //inner window (top)
      rect(x+margin, y+margin, w-margin*2, winHt);
      //inner windows (bottom)
      rect(x+margin, y+winHt+margin*2, w-margin*2, winHt);
      break;
    case 2:
      winWdth = (w-margin*3)/2;
      winHt = (h-margin*3)/2;
      //outer window (sash)
      rect(x, y, w, h);
      //inner window (top-left)
      rect(x+margin, y+margin, winWdth, winHt);
      //inner window (top-right)
      rect(x+winWdth+margin*2,  y+margin, winWdth, winHt);
      //inner windows (bottom-left)
      rect(x+margin, y+winHt+margin*2, winWdth, winHt);
      //inner windows (bottom-right)
      rect(x+winWdth+margin*2,  y+winHt+margin*2, winWdth, winHt);
      break;
    }
  }

  // set window style (number of panes)
  void setStyle(int style){
    this.style = style;
  }
}

class Roof{
  //roof properties
  int x;
  int y;
  int w;
  int h;

  // roof style
  int style = 0;
  //constants  
  final static int CATHEDRAL = 0;
  final static int GAMBREL = 1;
  final static int DOME = 2;

  // default constructor
  Roof(){
  }
   
   // constructor 2
   Roof(int style){
    this.style = style;
  }

  // draw the roof
  void drawRoof(int x, int y, int w, int h) {
    switch(style){
    case 0:
      beginShape();
      vertex(x, y);
      vertex(x+w/2, y-h/3);
      vertex(x+w, y);
      endShape(CLOSE);
      break;
    case 1:
     beginShape();
      vertex(x, y);
      vertex(x+w/7, y-h/4);
      vertex(x+w/2, y-h/2);
      vertex(x+(w-w/7), y-h/4);
      vertex(x+w, y);
      endShape(CLOSE);
      break;
    case 2:
      ellipseMode(CORNER);
      arc(x, y-h/2, w, h, PI, TWO_PI);
      line(x, y, x+w, y);
      break;
    }

  }

  // set roof style
  void setStyle(int style){
    this.style = style;
  }
}

class House{
  //house properties
  int x;
  int y;
  int w;
  int h;

  //component reference variables
  Door door;
  Window window;
  Roof roof;

  //optional autosize variable
  boolean AutoSizeComponents = false;

  //door placement
  int doorLoc = 0;
  //constants
  final static int MIDDLE_DOOR = 0;
  final static int LEFT_DOOR = 1;
  final static int RIGHT_DOOR = 2;

  //constructor
  House(int w, int h, Door door, Window window, Roof roof, int doorLoc) {
    this.w = w;
    this.h = h;
    this.door = door;
    this.window = window;
    this.roof = roof;
    this.doorLoc = doorLoc;
  }

  void drawHouse(int x, int y, boolean AutoSizeComponents) {
    this.x = x;
    this.y =y;
    this.AutoSizeComponents = AutoSizeComponents;

    //automatically sizes doors and windows
    if(AutoSizeComponents){
      //autosize door
      door.h = h/4;
      door.w = door.h/2;

      //autosize windows
      window.h = h/3;
      window.w = window.h/2;

    }
    // draw bldg block
    rect(x, y, w, h);

    // draw door
    switch(doorLoc){
    case 0:
      door.drawDoor(x+w/2-door.w/2, y+h-door.h);
      break;
    case 1:
      door.drawDoor(x+w/8, y+h-door.h);
      break;
    case 2:
      door.drawDoor(x+w-w/8-door.w,  y+h-door.h);
      break;
    }

    // draw windows
    int windowMargin = (w-window.w*2)/3;
    window.drawWindow(x+windowMargin, y+h/6);
    window.drawWindow(x+windowMargin*2+window.w, y+h/6);

    // draw roof
    roof.drawRoof(x, y, w, h);
  }

  // catch drawHouse method without boolean argument
  void drawHouse(int x, int y){
    // recall with required 3rd argument
    drawHouse(x, y, false);
  }
}

>>

Taken from [[basic/neighborhood.html|http://ejohn.org/apps/processing.js/examples/basic/neighborhood.html]]
The noLoop() function causes draw() to only execute once. Without calling noLoop(), draw() executed continually.

<<Processing 

// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set line drawing color to white
  frameRate(30);
  noLoop();
}

float y = 100;

// The statements in draw() are executed until the 
// program is stopped. Each statement is executed in 
// sequence and after the last line is read, the first 
// line is executed again.
void draw() 
{ 
  background(0);   // Set the background to black
  y = y - 1; 
  if (y < 0) { y = height; } 
  line(0, y, width, y);  
}

>>

Taken from [[basic/noloop.html|http://ejohn.org/apps/processing.js/examples/basic/noloop.html]]
Using 1D Perlin Noise to assign location.

<<Processing 

float xoff = 0.0;
float xincrement = 0.01; 

void setup() {
  size(200,200);
  background(0);
  frameRate(30);
  smooth();
  noStroke();
}

void draw()
{
  // Create an alpha blended background
  fill(0, 10);
  rect(0,0,width,height);
  
  //float n = random(0,width);  // Try this line instead of noise
  
  // Get a noise value based on xoff and scale it according to the window's width
  float n = noise(xoff)*width;
  
  // With each cycle, increment xoff
  xoff += xincrement;
  
  // Draw the ellipse at the value produced by perlin noise
  fill(200);
  ellipse(n,height/2,16,16);
}

>>

Taken from [[basic/noise1d.html|http://ejohn.org/apps/processing.js/examples/basic/noise1d.html]]
by Daniel Shiffman. Using 2D noise to create simple texture.

<<Processing 

float increment = 0.02;

void setup() {
  size(100,100);
  noLoop();
}

void draw() {
  background(0);
  
  // Optional: adjust noise detail here
  // noiseDetail(8,0.65f);
  
  loadPixels();

  float xoff = 0.0; // Start xoff at 0
  
  // For every x,y coordinate in a 2D space, calculate a noise value and produce a brightness value
  for