Vector Fields
A vector field is a visualization tool represented by an grid system, often 2D, that describe the behavior of vector quantities, such as velocity, force, or electric fields, at every point in a given space. Visualizing vector fields helps us understand how these quantities vary across space and can be crucial in solving various real-world problems. Visualizing vector fields using 2D grid systems is a fundamental concept in mathematics and physics, and we already encountered them in the Chapter of Cellular Automata: PathFinder.
Each tile in the system has a position in x and y. These two variables will be the input for a function.
The output of that mathematical function will then be remapped into an angle between 0 to 360 degrees.
The resulting angle will then be used to represent the direction in which a line emerging from the
center of each tile has to go.
The parameters of the Algorithm
- RES: int - The size of a TILE
- DIMS: (int,int) - Total number of columns and rows that make a grid
- SCREEN: (int,int) - Space in pixels that the grid occupies (width, height) and used to build a screen
- RANGE: float - The rescaling factor that will determine the domain of input values in x and y to the implicit function f(x,y)
- FORCE: int - The magnitud of a vector represented as the length of a line
- TILE: Tile() - Basic unit of information in the system
- GRID: [[TILE, ..., n=DIMS[0]], ..., n=DIMS[1]] - A 2D array of TILE
- TIME: float - A third variable that enters as argument to the function f(x,y,t) representing changes in time
- (opt)LIST_OF_PARTICLE: [Particle(), ..., n=100] - A collection of particles that will be placed on the GRID with the purpose of animation
# MODULES import pygame import math import random # DD RES = 16 DIMS = (40, 40) SCREEN = (RES * DIMS[0], RES * DIMS[1]) display = pygame.display.set_mode(SCREEN) RANGE = 3 FORCE = (RES//4) * 3 # DD. TILE # tile = Tile() # interp. the basic unit of information in the program. A square in the grid class Tile: def __init__(self, c, r): self.c = c self.r = r self.x = self.c * RES self.y = self.r * RES self.rect = pygame.Rect(self.x, self.y, RES, RES) self.color = "#1e1e1e" # attr. related to angle self.center = (self.x + RES//2, self.y + RES//2) self.dx = 0 self.dy = 0 def drawTile(self): pygame.draw.rect(display, self.color, self.rect) def drawLine(self): pygame.draw.line(display, "red", self.center, (self.center[0]+self.dx,self.center[1]+self.dy), 1) # DD. TILEROW # tileRow = [TILE, ..., n=DIMS[0]] # interp. a row of TILE, each tile is next to the other tileRow = [] for c in range(DIMS[0]): # create tile = Tile(c, 0) # append tileRow.append(tile) # TEMPLATE FOR TILEROW # for tile in tileRow: # ... tile # DD. GRID # grid = [TILEROW, ..., n = DIMS[1]] # interp. a 2D array of TILE grid = [] for r in range(DIMS[1]): tileRow = [] for c in range(DIMS[0]): # create tile = Tile(c, r) # append tileRow.append(tile) grid.append(tileRow) # TEMPLATE FOR GRID # for tileRow in grid: # for tile in tileRow: # ... tile # DD. TIME # t = float # interp. a third dimension that shapes the grid by modifying the function f(x,y,t) to animate the grid t = 0.0 # DD. PARTICLE # particle = Particle() # interp. a particle that travels the vector field class Particle: def __init__(self,x,y): self.x = x self.y = y self.rect = pygame.Rect(self.x, self.y, 5,5) self.color = "blue" self.dx = 0 self.dy = 0 def draw(self): self.rect.center = self.x, self.y self.x += self.dx self.y += self.dy pygame.draw.circle(display,self.color,(self.x, self.y),5) # DD. LIST_OF_PARTICLE # lop = [PARTICLE, ..., n=100] # interp. a collection of PARTICLE that are updated every frame lop = [] for i in range(100): particle = Particle(random.randint(0,SCREEN[0]),random.randint(0,SCREEN[1])) lop.append(particle) # TEMPLATE FOR LIST_OF_PARTICLE # for particle in lop: # ... particle
The Algorithm
- For each TILE in GRID:
- Remap TILE c and TILE r into the new values x and y in the range (-RANGE,RANGE)
- Obtain the value of the function f(x,y,t) with x,y,t. Then remap from 0-360 to get an ANGLE
- Calculate new vector (dx,dy) using the ANGLE and the formulas cosine(angle) and sine(angle), adding the position of TILE as an offset in x and y
- Make t slightly bigger