At this point you should probably worry more about picking up the basics of programming than the maths behind solving your problem. In fact, let's make the math problem super simple for now, so the code doesn't get too complicated: let's pretend your patterns are squares and you're interested in only the distance from the centre of a circle to the centre of a 'pattern'/square.
The ellipse() function for example will only do one thing - will draw an ellipse on screen, but you will need something to keep track of the properties of the ellipse you use (like position and size).
One way to keep track of the properties is to store them in an array:
int numEllipses = 100;
float[] ellipseXValues = new float[numEllipses];
float[] ellipseYValues = new float[numEllipses];
float[] ellipseSizeValues = new float[numEllipses];
//etc.
For each property you'll use an array since you'll have multiple ellipse 'objects'. Similar for patterns. If you're not already familiar with arrays, then doing things this way is a good exercise. You will notice you're code will get pretty long pretty fast, but what code looks like matters less when you learn: it's more about understand and keeping tracking of what you do (not "bitting more than what one can chew").
Another way to do this is to use classes. Classes are cool because they allow you to encapsulate properties and functionalities related to an idea you think of. For example you can create your own Ellipse
class or a Pattern
class which will hold the properties you want to use (like position, colour, etc.) but can also have functions (like a draw() function where an Ellipse would render itself on screen one way, but a Pattern in another) and so on.
Here's an example:
class Circle{
float x,y,vx,vy,size;//store position(x,y), velocity(vx,vy) and size
color clr; //store color
Circle(float ax,float ay,float as,color ac){
x = ax;
y = ay;
size = as;
clr = ac;
vx = random(-.1,.1);//random velocity
vy = random(-.1,.1);
}
void update(int w,int h){
x += vx;//update position based on velocity
y += vy;
if(x < 0 || x > w) vx *= -1;//check bounds and flip velocity if there's a collision
if(y < 0 || y > h) vy *= -1;
}
void draw(){
pushStyle();//start isolating drawing commands
noStroke();
fill(clr);
ellipse(x,y,size,size);
popStyle();//stop isolating drawing commands
}
}
A class is like a template/blueprint - it can be anything you want. For example you can have a Vehicle
class which has a property numberOfWheels
which determines how the instances/objects created from this class will look like: a bike for 2, car for 4, etc. Similarly you can have a Pattern
class and it might have a various properties/variables related to it: number of stripes/dots, a list of colours, etc.
Here's a basic example of how to use the Circle class:
Circle c;
void setup(){
size(400,400);
smooth();
c = new Circle(200,200,20,color(192));//create a new object from the template/class using the *new* keyword
}
void draw(){
background(255);
c.x = mouseX;//access and modify properties of the object
c.y = mouseY;
c.size = map(mouseX,0,width,20,200);
c.clr = color(map(mouseY,0,height,0,240));
c.draw();//call a function/method of the object
}
Notice the difference between the definition/class and the object (instantiated with new).
In case you're not familiar with classes already check out Daniel Shiffman's excellent Objects tutorial. In Processing you can explore Examples > Basics > Objects > Objects.
(less important: I'm using the map() function to easily link mouse positions to properties of the circle like size and colour.)
Now that you can create your own type/class, you can also create arrays of such objects.
There's a basic example that ships with Processing: Examples > Basics > Arrays > ArrayObjects
Here's how we use the Circle class (and a very similar Square) class together in two separate arrays and check distances:
int maxCircles = 20;
int maxSquares = 3;
float minDist = 50;
Circle[] circles = new Circle[maxCircles];//create an array Circle objects/instances
Square[] squares = new Square[maxSquares];
void setup(){
size(400,400);
smooth();
colorMode(HSB,360,100,100);
for(int i = 0; i < maxCircles; i++) circles[i] = new Circle(random(width),random(height),random(4,10),color(0,0,100));
for(int i = 0; i < maxSquares; i++) squares[i] = new Square(random(width),random(height),random(4,10),color(240));
}
void draw(){
background(0,0,95);
for(int i = 0; i < maxCircles; i++){
circles[i].update(width,height);
for(int j = 0; j < maxSquares; j++){
squares[j].update(width,height);
//use the dist() function to compute distances
float distance = dist(circles[i].x,circles[i].y,squares[j].x,squares[j].y);
if(distance < minDist){//based on that, if within a threshold, map colours/etc.
circles[i].clr = color( 0,map(distance,0,minDist,100,0),100);
}
squares[j].draw();
}
circles[i].draw();
}
}
class Circle{
float x,y,vx,vy,size;//store position(x,y), velocity(vx,vy) and size
color clr; //store color
Circle(float ax,float ay,float as,color ac){
x = ax;
y = ay;
size = as;
clr = ac;
vx = random(-.1,.1);//random velocity
vy = random(-.1,.1);
}
void update(int w,int h){
x += vx;//update position based on velocity
y += vy;
if(x < 0 || x > w) vx *= -1;//check bounds and flip velocity if there's a collision
if(y < 0 || y > h) vy *= -1;
}
void draw(){
pushStyle();//start isolating drawing commands
noStroke();
fill(clr);
ellipse(x,y,size,size);
popStyle();//stop isolating drawing commands
}
}
class Square{
float x,y,vx,vy,size;
color clr;
Square(float ax,float ay,float as,color ac){
x = ax;
y = ay;
size = as;
clr = ac;
vx = random(-.02,.02);//random velocity
vy = random(-.02,.02);
}
void update(int w,int h){
x += vx;
y += vy;
if(x < 0 || x > w) vx *= -1;
if(y < 0 || y > h) vy *= -1;
}
void draw(){
pushStyle();
noStroke();
fill(clr);
rect(x-size/2,y-size/2,size,size);
popStyle();
}
}
As you can see in the commented code, after the complex concepts are somewhat simplified/encapsulated, it's just a matter of looping through arrays and checking distances (using dist()).
Here's a quick preview, where tiny squares 'pretend' to be pattens and affect the colour of circles around themselves:

You can also run the code online or bellow:
var maxCircles = 20;
var maxSquares = 3;
var minDist = 150;
var circles = new Array(maxCircles);
var squares = new Array(maxSquares);
function setup(){
createCanvas(400,400);
smooth();
colorMode(HSB,360,100,100);
for(var i = 0; i < maxCircles; i++) circles[i] = new Circle(random(width),random(height),random(4,10),color(0,0,100));
for(i = 0; i < maxSquares; i++) squares[i] = new Square(random(width),random(height),random(4,10),color(240));
}
function draw(){
background(0,0,95);
for(var i = 0; i < maxCircles; i++){
circles[i].update(width,height);
for(var j = 0; j < maxSquares; j++){
squares[j].update(width,height);
var distance = dist(circles[i].x,circles[i].y,squares[j].x,squares[j].y);
if(distance < minDist){
circles[i].clr = color( 0,map(distance,0,minDist,100,0),100);
}squares[j].draw();
}
circles[i].draw();
}
}
function Circle(ax,ay,as,ac){
this.x = ax;
this.y = ay;
this.size = as;
this.clr = ac;
this.vx = random(-.1,.1);//random velocity
this.vy = random(-.1,.1);
this.update = function(w,h){
this.x += this.vx;
this.y += this.vy;
if(this.x < 0 || this.x > this.w) this.vx *= -1;
if(this.y < 0 || this.y > this.h) this.vy *= -1;
}
this.draw = function(){
push();
noStroke();
fill(this.clr);
ellipse(this.x,this.y,this.size,this.size);
pop();
}
}
function Square(ax,ay,as,ac){
this.x = ax;
this.y = ay;
this.size = as;
this.clr = ac;
this.vx = random(-.02,.02);//random velocity
this.vy = random(-.02,.02);
this.update = function(w,h){
this.x += this.vx;
this.y += this.vy;
if(this.x < 0 || this.x > this.w) this.vx *= -1;
if(this.y < 0 || this.y > this.h) this.vy *= -1;
}
this.draw = function(){
push();
noStroke();
fill(this.clr);
rect(this.x-this.size/2,this.y-this.size/2,this.size,this.size);
pop();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>
Hopefully this explains one basic way to deal with the problem. After you've found yourself comfortable with the syntax and some programming concepts it should be a lot easier to dive into slightly more things:
- you might find arrays somewhat limiting because of they're fixed size and could explore ArrayList
- you might find the basic distance function is not precise enough for your complex patterns and can find other ways of computing distances.
Goodluck