{"id":328,"date":"2011-11-30T01:00:34","date_gmt":"2011-11-30T09:00:34","guid":{"rendered":"http:\/\/new.joyofprocessing.com\/blog\/?p=328"},"modified":"2011-11-28T20:23:08","modified_gmt":"2011-11-29T04:23:08","slug":"truchet-tiles","status":"publish","type":"post","link":"https:\/\/joyofprocessing.com\/blog\/2011\/11\/truchet-tiles\/","title":{"rendered":"Truchet Tiles"},"content":{"rendered":"<p><script type=\"application\/processing\">\/\/ Truchet Tiles - Jim Bumgardner\n\nint gridW = 24;\nint gridH = 24;\nint cellW, cellH;\n\nint nbrCells = gridW * gridH;\n\nCell[] cells = new Cell[nbrCells];\nPGraphics tile1, tile2;\n\nPGraphics makeTile(boolean state)\n{\n  PGraphics g = createGraphics(cellW, cellH, JAVA2D);\n  g.beginDraw();\n  g.colorMode(RGB, 256);\n  g.smooth();\n  g.background(255);\n  g.stroke(0);\n  g.strokeWeight(4);\n  g.noFill();\n  if (state) {\n    g.ellipse(0, 0, cellW, cellH);\n    g.ellipse(cellW, cellH, cellW, cellH);\n  } else {\n    g.ellipse(0, cellH, cellW, cellH);\n    g.ellipse(cellW, 0, cellW, cellH);\n  }\n  g.endDraw();  \n  return g;\n}\n\nvoid setup()\n{\n  size(500,500);\n  smooth();\n\n  \/\/ I use ceil to round up, which insures the tiles go all the way across the screen, \n  \/\/ without the gap caused by rounding down.\n\n  cellW = ceil(width\/(float) gridW);\n  cellH = ceil(height\/(float) gridH);\n  \n  tile1 = makeTile(false);\n  tile2 = makeTile(true);\n\n  for (int i = 0; i < nbrCells; ++i) {\n    int px = cellW * (int) (i % gridW);\n    int py = cellH * (int) (i \/ gridW);\n    cells[i] = new Cell(px, py, i);\n  }\n  noCursor();\n  noLoop();\n}\n\nvoid draw()\n{\n  background(255);\n  for (int i = 0; i < nbrCells; ++i) {\n    cells[i].render();\n  }\n}\n\nint lastN = -1;\nvoid mouseMoved()\n{\n  int gx = (int) (mouseX \/ cellW);\n  int gy = (int) (mouseY \/ cellH);\n  int n = constrain(gy*gridW+gx,0,nbrCells-1);\n  if (n != lastN) {\n    cells[n].state = !cells[n].state;\n    lastN = n;\n    redraw();\n  }\n}\n\nclass Cell\n{\n  int px,py;\n  int idx;\n  boolean state;\n  Cell(int _px, int _py, int _idx)\n  {\n    px = _px;\n    py = _py;\n    idx = _idx;\n    state = random(1) < .5? false : true;\n  }\n\n  void render() \n  {\n    image(state? tile1 : tile2, px, py, cellW, cellH);\n  }\n}\n\n<\/script><\/p>\n<div class=\"ps_cap\"><a href=\"\/showexample.php?ex=truchet_tiles\">source<\/a><\/div>\n<p>This Truchet tiling consists of a grid constructed from only two tiles, shown below.<\/p>\n<p><img decoding=\"async\" src=\"\/img\/truchet_examples.png\" \/><\/p>\n<p>To speed up rendering, I&#8217;ve pre-rendered the tiles onto two offscreen graphics objects.  The tiles are then rendered in a loop.<\/p>\n<pre>\r\nvoid draw()\r\n{\r\n  background(255);\r\n  for (int i = 0; i < nbrCells; ++i) {\r\n    cells[i].render();\r\n  }\r\n}\r\n<\/pre>\n<p>The render function for each cell looks at the cell's current state, and uses that to select the correct tile.  I'm using the conditional operator (?:) to select the tile (tile1 or tile2) based on the value of the boolean variable <i>state<\/i>.<\/p>\n<pre>\r\n  void render() \r\n  {\r\n    image(state? tile1 : tile2, px, py, cellW, cellH);\r\n  }\r\n<\/pre>\n<p>When you move the mouse, I figure out which tile falls under the mouse pointer, and flip its state. To make the effect more obvious, I've hidden the mouse pointer using noCursor().<\/p>\n","protected":false},"excerpt":{"rendered":"<p>source This Truchet tiling consists of a grid constructed from only two tiles, shown below. To speed up rendering, I&#8217;ve pre-rendered the tiles onto two offscreen graphics objects. The tiles are then rendered in a loop. void draw() { background(255); for (int i = 0; i < nbrCells; ++i) { cells[i].render(); } } The render [&hellip;]\n<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[8,15,25],"class_list":["post-328","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-intermediate","tag-symmetry","tag-tilings"],"_links":{"self":[{"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/posts\/328","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/comments?post=328"}],"version-history":[{"count":6,"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/posts\/328\/revisions"}],"predecessor-version":[{"id":349,"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/posts\/328\/revisions\/349"}],"wp:attachment":[{"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/media?parent=328"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/categories?post=328"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/joyofprocessing.com\/blog\/wp-json\/wp\/v2\/tags?post=328"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}