WTF is this?

The images you see on this blog are output from various Ulam spiral generators I built in Flash, Python and most recently using Arduino. Generally, each dot in an image represents a number with integer 1 at center. In addition to writing algorithms to test each number for primality within a set I have discovered that an infinite number of calculations can be performed to create new designs and animation algorithms. The simplicity and speed of these algorithms make them an ideal fit for embedded systems graphics, scientific, mathematical and artistic explorations.

Thursday, July 31, 2014

Displaying Ulam Spirals with Arduino Yun and 128x160 Display


I just set up a small 128x160 LCD display with an Arduino Yun running full animations of the Ulam Spiral. 
Here's the adafruit tutorial I used to get going: http://www.adafruit.com/products/358

Notes: the redraw rate is pretty slow, around 1 frame per 3 seconds or so. Definitely not as fast as the LED panel I wired up. It's still very interesting to watch the spirals develop like this and much faster then Flash. The other cool thing about this build is the Yun, which I have connected to a wireless network. It's very easy to update the board remotely. 

Here's the code from my sketch: 

//spiral algo written by arlo emerson arloemerson@gmail.com
//adapted from the ulam spiral aglorithm
//2014
//http://ulamspiral.blogspot.com/

#define PI 3.1415926535897932384626433832795

#define sclk 4
#define mosi 5
#define cs   6
#define dc   7
#define rst  8 


#include    // Core graphics library
#include // Hardware-specific library
#include

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);

#define Neutral 0
#define Press 1
#define Up 2
#define Down 3
#define Right 4
#define Left 5


float _piCounter = .005;
int _globalCounter = 2;

void setup(void) {
  Serial.begin(9600);

  tft.initR(INITR_BLACKTAB); 

  uint16_t time = millis();
  tft.fillScreen(ST7735_BLACK);
  time = millis() - time;

  tft.drawPixel(tft.width() / 2, tft.height() / 2, ST7735_GREEN);

  printWelcomeText();

  initSpiral();
}

void loop()
{

  initSpiral();

  _piCounter += .001;
  delay(200);
  _globalCounter += 1;

  if (_globalCounter == 10)
  {
    printWelcomeText();
    _globalCounter = 0;

  }
}


void initSpiral()
{
  int posX = tft.width() / 2;
  int posY = tft.height() / 2;
  int numberCounter = 1;
  int _spacer = 1;
  int legLength = 0;

  //establish the first dot
  tft.drawPixel(posX, posY, ST7735_WHITE);

  for (int i = 1; i < 60; i++)
  {
    for (int k = 0; k <= legLength; k++)
    {
      numberCounter += 1;
      posX += _spacer;
      testNumber(numberCounter, posX, posY);
    }

    for (int k = 0; k <= legLength; k++)
    {
      numberCounter += 1;
      posY -= _spacer;
      testNumber(numberCounter, posX, posY);
    }

    legLength += 1;

    for (int k = 0; k <= legLength; k++)
    {
      numberCounter += 1;
      posX -= _spacer;
      testNumber(numberCounter, posX, posY);
    }

    for (int k = 0; k <= legLength; k++)
    {
      numberCounter += 1;
      posY += _spacer;
      testNumber(numberCounter, posX, posY);
    }

    legLength += 1;
  }
}

void testNumber(int pNumber, int pX, int pY)
{
  //int tmpMultiplier = _piCounter * 1.1;
  //if (round(sqrt(pow(pNumber,2))*(1.6180339887*PI)/2)%2==0)
  //if (round(  pow(sqrt(pNumber)/PI, tmpGradient) )%2==0)
  //Serial.println(_piCounter);
  //if (round( sqrt( pow(pNumber, 2 ))*_piCounter * PI) % 2 == 0)
  //if (round(sqrt(pow(pNumber,2))*((.9 * _piCounter) *PI)/2)%2==0)
  if (  round( (pX*pY)* pow(sqrt(pNumber)/PI, 1.23456789)*_piCounter )%3==0)
  {
    //    matrix.drawPixel(pX, pY, matrix.Color333(_bigNumber.charAt(pX), _bigNumber.charAt(pY), _bigNumber.charAt(_globalCounter)));

    tft.drawPixel(pX, pY, ST7735_WHITE);
  }
  else
  {
    tft.drawPixel(pX, pY, ST7735_RED);
  }
}

void printWelcomeText()
{
  tft.setCursor(0, 0);
  tft.fillScreen(ST7735_BLACK);
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(2);
  tft.println("Ulam");
  tft.setTextColor(ST7735_WHITE);
  tft.println("Spirals");
  tft.setTextColor(ST7735_RED);
  tft.println("Forever");
  delay(3000);
  tft.fillScreen(ST7735_BLACK);
}




Wednesday, July 30, 2014

Ulam Spirals Using Arduino and LED Displays


Here's an animated gif of my Arduino-powered 32x16 LED screen. I wired this up using the Adafruit tutorial at https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/wiring-the-16x32-matrix

The code to generate the spiral. Note this is unoptimized. You can probably do it better. The basic nugget to get the spiral is this line: round( sqrt( pow(pNumber, 2 ))*_piCounter*PI)%2==0).

void loop()
{
   initSpiral();
  _piCounter += .001;
  delay(200);
  _globalCounter += 1;
}

void initSpiral()
{
  int posX = 15;
  int posY = 7;
  int numberCounter = 1;
  int _spacer = 1;
  int legLength = 0;

  //establish the first dot
  //matrix.drawPixel(x, y, matrix.Color333(r, g, b));
  matrix.drawPixel(posX, posY, matrix.Color333(3, 4, 5));


  for (int i=1;i<17 font="" i="">
  {
    for (int k=0;k<=legLength;k++)
    {
      numberCounter += 1;
      posX += _spacer;
      testNumber(numberCounter, posX, posY);
    }

    for (int k=0;k<=legLength;k++)
    {
      numberCounter += 1;
      posY -= _spacer;
      testNumber(numberCounter, posX, posY);
    }    

    legLength += 1;

    for (int k=0;k<=legLength;k++)
    {
      numberCounter += 1;
      posX -= _spacer;
      testNumber(numberCounter, posX, posY);
    }

    for (int k=0;k<=legLength;k++)
    {
      numberCounter += 1;
      posY += _spacer;
      testNumber(numberCounter, posX, posY);
    }

    legLength += 1;
  }
}


String _bigNumber = "01234567012345670123456701234567012345670123456701234567012345670123456701234567012345670123456701234567012345670123456701234567";


void testNumber(int pNumber, int pX, int pY)
{
  if (round( sqrt( pow(pNumber, 2 ))*_piCounter*PI)%2==0)
  {
    matrix.drawPixel(pX, pY, matrix.Color333(_bigNumber.charAt(pX), _bigNumber.charAt(pY), _bigNumber.charAt(_globalCounter)));
  }
  else
  {
    matrix.drawPixel(pX, pY, matrix.Color333(3, 0, 2));
  }
}

Interesting note: these 32x16 panels are so incredibly bright they are painful to look at. So I'm using two sheets of paper to stop down the light, which also has a nice diffusion effect.

Sunday, May 23, 2010

Gaussian White Noise Wave Functions

Various examples of ulam spirals using a continuous tube to plot the points in conjunction with a white noise wave function to plot the z-coordinate. Generator written in Python using the VPython library.






Some other shapes using the gaussian white noise to determine dimensions of plot objects.




Monday, April 6, 2009

Spiral Video Series

Using smplayer/mencoder to convert PNG output to video. Formula and other control info is automatically inserted into the beginning of the video. This set is using a 2x2 pixel plotted out using the Ulam spiral "RULD" method. Pixel is black or red if the pixel number (pInt) passes the following test (e.g.): if round(((pInt)*pi)*pow(sqrt(pInt)/pi+(_multiplier/9), (1.2)) )%2==0: Iterating the value of _multiplier (or any other variable), we generate a new PNG file when the _range value is met. Stitching these images together into a video reveals motion within the overall pattern. For example, incrementing _multiplier very slightly for each image creates less disruption from one image to the next. Frame rate varies, generally within 2 to 15 FPS. Too bad blogger is overcompressing these, they are quite nice before they hit the FLV codec. C'est la vie.




Here's one of the first videos I cobbled together, a very quick prototype...

Thursday, April 2, 2009

Random Grids




Detail:


I was bored today so I modified the base routine to select a cardinal direction randomly. These images are all built pulling from a list of 1,296 possible 2x2 pixel images. The original image is...

Saturday, November 1, 2008

Jaco Pastorius, Meet Stanislaw Ulam



These are all using a very simple test for n, round( pow(pInt,sqrt(1))/pi )%2==0





Enter Jeff Buckley




...and Jimi