Last active
January 1, 2021 13:15
-
-
Save elbosso/8e6cf0fb700f6be6452399c1b399c6c5 to your computer and use it in GitHub Desktop.
Truchet tiling - conceived after going down yet another rabbithole because of operation mindfuck@rc3 (https://media.ccc.de/v/rc3-501024-operation_mindfuck_vol_4)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2021. | |
* | |
* Juergen Key. Alle Rechte vorbehalten. | |
* | |
* Weiterverbreitung und Verwendung in nichtkompilierter oder kompilierter Form, | |
* mit oder ohne Veraenderung, sind unter den folgenden Bedingungen zulaessig: | |
* | |
* 1. Weiterverbreitete nichtkompilierte Exemplare muessen das obige Copyright, | |
* die Liste der Bedingungen und den folgenden Haftungsausschluss im Quelltext | |
* enthalten. | |
* 2. Weiterverbreitete kompilierte Exemplare muessen das obige Copyright, | |
* die Liste der Bedingungen und den folgenden Haftungsausschluss in der | |
* Dokumentation und/oder anderen Materialien, die mit dem Exemplar verbreitet | |
* werden, enthalten. | |
* 3. Weder der Name des Autors noch die Namen der Beitragsleistenden | |
* duerfen zum Kennzeichnen oder Bewerben von Produkten, die von dieser Software | |
* abgeleitet wurden, ohne spezielle vorherige schriftliche Genehmigung verwendet | |
* werden. | |
* | |
* DIESE SOFTWARE WIRD VOM AUTOR UND DEN BEITRAGSLEISTENDEN OHNE | |
* JEGLICHE SPEZIELLE ODER IMPLIZIERTE GARANTIEN ZUR VERFUEGUNG GESTELLT, DIE | |
* UNTER ANDEREM EINSCHLIESSEN: DIE IMPLIZIERTE GARANTIE DER VERWENDBARKEIT DER | |
* SOFTWARE FUER EINEN BESTIMMTEN ZWECK. AUF KEINEN FALL IST DER AUTOR | |
* ODER DIE BEITRAGSLEISTENDEN FUER IRGENDWELCHE DIREKTEN, INDIREKTEN, | |
* ZUFAELLIGEN, SPEZIELLEN, BEISPIELHAFTEN ODER FOLGENDEN SCHAEDEN (UNTER ANDEREM | |
* VERSCHAFFEN VON ERSATZGUETERN ODER -DIENSTLEISTUNGEN; EINSCHRAENKUNG DER | |
* NUTZUNGSFAEHIGKEIT; VERLUST VON NUTZUNGSFAEHIGKEIT; DATEN; PROFIT ODER | |
* GESCHAEFTSUNTERBRECHUNG), WIE AUCH IMMER VERURSACHT UND UNTER WELCHER | |
* VERPFLICHTUNG AUCH IMMER, OB IN VERTRAG, STRIKTER VERPFLICHTUNG ODER | |
* UNERLAUBTE HANDLUNG (INKLUSIVE FAHRLAESSIGKEIT) VERANTWORTLICH, AUF WELCHEM | |
* WEG SIE AUCH IMMER DURCH DIE BENUTZUNG DIESER SOFTWARE ENTSTANDEN SIND, SOGAR, | |
* WENN SIE AUF DIE MOEGLICHKEIT EINES SOLCHEN SCHADENS HINGEWIESEN WORDEN SIND. | |
* | |
*/ | |
//inspired by | |
//https://christophercarlson.com/portfolio/multi-scale-truchet-patterns/ | |
//https://media.ccc.de/v/rc3-501024-operation_mindfuck_vol_4 | |
package de.elbosso.scratch.algorithms.graphics; | |
import java.awt.*; | |
import java.awt.geom.AffineTransform; | |
import java.awt.image.BufferedImage; | |
import java.io.IOException; | |
public class Truchet extends java.lang.Object | |
{ | |
private final java.util.Random rand=new java.util.Random(System.currentTimeMillis()); | |
public Truchet(java.awt.Dimension dim,int tilesize,boolean evenOdd,java.io.File f) throws IOException | |
{ | |
super(); | |
int minTilesize=tilesize/8+1; | |
java.awt.image.BufferedImage bimg=produceImage(dim,tilesize,minTilesize,evenOdd); | |
javax.imageio.ImageIO.write(bimg,"png",f); | |
} | |
public static void main(java.lang.String[] args) throws IOException | |
{ | |
java.io.File f=java.io.File.createTempFile("truchet",".png"); | |
System.out.println(f); | |
Truchet truchet=new Truchet(new java.awt.Dimension(4,4),256,true,f); | |
} | |
private java.awt.image.BufferedImage produceImage(java.awt.Dimension dim,int tilesize,int minTilesize,boolean evenOdd) | |
{ | |
java.awt.image.BufferedImage bimg=new java.awt.image.BufferedImage((dim.width+1)*tilesize,(dim.height+1)*tilesize, BufferedImage.TYPE_INT_ARGB); | |
java.awt.Graphics2D g2=bimg.createGraphics(); | |
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); | |
g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY); | |
int size=bimg.getHeight(); | |
for(int y=0;y<dim.height;++y) | |
{ | |
double ycoord=(double)y/(double)(dim.height+1)*(double)size; | |
for(int x=0;x<dim.width;++x) | |
{ | |
double xcoord=(double)x/(double)(dim.width+1)*(double)size; | |
g2.drawImage(produceTile(tilesize, rand.nextBoolean(), evenOdd?Color.black:Color.WHITE,evenOdd? Color.white: Color.black),(int)xcoord,(int)ycoord,null); | |
} | |
} | |
for(int y=0;y<dim.height;++y) | |
{ | |
double ycoord=(double)y/(double)(dim.height+1)*(double)size; | |
for(int x=0;x<dim.width;++x) | |
{ | |
double xcoord=(double)x/(double)(dim.width+1)*(double)size; | |
if((rand.nextBoolean())&&(minTilesize<tilesize/2)) | |
g2.drawImage(produceImage(new java.awt.Dimension(2,2),tilesize/2,minTilesize,!evenOdd),(int)xcoord+tilesize/4,(int)ycoord+tilesize/4,null); | |
} | |
} | |
g2.dispose(); | |
return bimg; | |
} | |
private BufferedImage produceTile(int size,boolean rotated,java.awt.Paint a, java.awt.Paint b) | |
{ | |
java.awt.image.BufferedImage rv=new java.awt.image.BufferedImage(size*2,size*2, BufferedImage.TYPE_INT_ARGB); | |
java.awt.Graphics2D g2=rv.createGraphics(); | |
double oneThird=.333333*(double)size; | |
double onesixth=0.5*oneThird; | |
double twoThirds=.666667*(double)size; | |
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); | |
g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY); | |
if(rotated==true) | |
{ | |
g2.setTransform(AffineTransform.getQuadrantRotateInstance(1,size,size)); | |
} | |
g2.setPaint(a); | |
g2.fillRect(size/2,size/2,size,size); | |
g2.setPaint(b); | |
g2.fillArc(-(int)onesixth,-(int)onesixth,size+(int)oneThird,size+(int)oneThird,0,-90); | |
g2.fillArc(size-(int)onesixth,size-(int)onesixth,size+(int)oneThird,size+(int)oneThird,90,90); | |
g2.fillOval(size-(int)onesixth,size/2-(int)onesixth,(int)oneThird,(int)oneThird); | |
g2.fillOval(size-(int)onesixth,size*3/2-(int)onesixth,(int)oneThird,(int)oneThird); | |
g2.fillOval((int)oneThird,size-(int)onesixth,(int)oneThird,(int)oneThird); | |
g2.fillOval((int)oneThird+size,size-(int)onesixth,(int)oneThird,(int)oneThird); | |
g2.setPaint(a); | |
g2.fillOval(size/2+(int)-oneThird,size/2+(int)-oneThird,(int)twoThirds,(int)twoThirds); | |
g2.fillOval(size/2+(int)twoThirds,size/2+(int)twoThirds,(int)twoThirds,(int)twoThirds); | |
g2.fillOval(size/2+(int)+twoThirds,size/2+(int)-oneThird,(int)twoThirds,(int)twoThirds); | |
g2.fillOval(size/2+(int)-oneThird,size/2+(int)twoThirds,(int)twoThirds,(int)twoThirds); | |
g2.dispose(); | |
return rv; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment