# PNG Pixel Forces Challenge

A Pixel World is a PNG image where gravitational, electromagnetic, and nuclear forces no longer exist. Special forces known as "pixel forces" are all that remain. We define this force as

Fp->q = a * (p * q) / (r * r) * r̂

• F is the pixel force that p exerts on q
• a is Adams' constant, defined as a = 4.2 * 10 ^ 1
• p and q are charges on two pixels
• r is the distance from p to q
• r̂ is the direction of r in radians, measured counterclockwise* from the positive x-axis

*There are infinitely many acceptable values for any given direction. For example, 6.28, 0, -6.28, and -12.57 radians are all equivalent, and would all be accepted.

Three types of pixels exist:

• A red pixel holds a charge of positive one
• A black pixel holds a charge of negative one
• A white pixel holds a charge of zero

The bottom left pixel of pixel world is located at (0, 0). The positive y axis falls up the page, and the positive x axis falls to the right. The total force on a pixel is simply the vector sum of all forces exerted upon that pixel. Like charges repel, and opposite charges attract.

Given a file path to a Pixel World, as well as two integers x and y, output the total force exerted on the pixel at location (x, y) in the format <magnitude>\n<direction>. Output must be accurate to at least 2 decimal places, but you may output more if you want. Direction must be output in radians. The integers x and y are guaranteed to be within the world boundary.

Deliverables

You must include a program, and a command that can be used to run your program. Two examples:

python AbsolutelyPositive.py "C:\Pixtona.png" 50 40
java UltimateAttraction "C:\Jupix.png" 30 30

Example Image

In the image below, there is a black pixel at (100, 104).

Pixars.png Example Output

This output does not correspond to the above input.

534.19721014
4.32605416

Need help getting started?

I wrote some example code here. I haven't tested it, so use it at your own risk.

• Can it be PPM instead of PNG? and typically, images put 0,0 in top left corner, do we have to rotate it? – user137 Aug 29 '14 at 15:27
• @user137 Everyone has to handle the PNG image format. I'm considering posting some Java code to get people started. I don't want to start adding optional requirements. The bottom left was selected as (0,0) because this allows us to use a right hand coordinate system and measure radians counterclockwise from the positive x-axis. If we place (0,0) in the top left, and radians would be measured clockwise from the positive x-axis. No matter which way you do it, some standard will unfortunately be broken. Couldn't you just flip the image anyway? – Rainbolt Aug 29 '14 at 15:33
• I love the intro picture... – trichoplax Aug 29 '14 at 17:28
• I think the choice for PNG will really hold people back, except those with ready knowledge of Java — which, as far as I know, is the only language with something like ImageIO. C++, for one, doesn't have it. – tomsmeding Aug 30 '14 at 9:40
• Nice challenge. PNG is fine IMO. Btw, here are some questions I have while attempting it. 1. I'm not sure if is it me, but I can't seem to find the black pixel in (99,101) in the image. 2. Is the example output the answer for the test image? 3. For the direction, if the angle is < pi degrees clockwise from the +ve x-axis, is negative values (i.e. 0 < Angle < pi) allowed, or must it be (pi < Angle < 2*pi) ? – Vectorized Aug 30 '14 at 15:47

## Python - 355

import sys,Image,math as m
i=Image.open(sys.argv)
w,h=i.size
X,Y=map(int,sys.argv[2:])
t=m.atan2
c=lambda i,j:2*(a[i,j]>200)-(a[i,j]>200)-1
p=c(X,h-1-Y)
V=H=0
for j in range(h):
for i in range(w):q=c(i,h-1-j);y=Y-j;x=X-i;r=x*x+y*y;f=r and 42.*p*q/r;V+=m.cos(t(x,y))*f;H+=m.sin(t(x,y))*f
d=t(V,H)
print(V**2+H**2)**.5,[d,m.pi*2+d][d<0]


Ungolfed

import sys
import Image
import math as m

X,Y=map(int,sys.argv[2:]) # The X and Y coordinates of the test pixel

i=Image.open(sys.argv) # Open the image
w,h=i.size # Get the width and height of the image
a=i.load() # Get a pixel access object of the image
V=0 # V = vector sum of Vertical Forces
H=0 # H = vector sum of Horizontal Forces

# Function to calculate the charge of the a pixel at x=i, y=j
def c(i,j):
global a
if a[i,j]>200: # If Red > 200
if a[i,j]>200: # If Green > 200
return 0 # We assume that pixel is White
else:
return 1 # We assume that pixel is Red
return -1 # Else, we asusme that pixel is Black

p=c(X,h-1-Y) # Assign the charge of the test pixel to p

for j in range(h): # For every y value...
for i in range(w): # For every x value...
q=c(i,h-1-j) # Assign the charge of the current pixel to q
y=Y-j # The y distance of the test pixel from the current pixel
x=X-i # The x distance of the test pixel from the current pixel
rSquared=x*x+y*y # The r-squared distance between the 2 pixels
f=rSquared and 42.*p*q/rSquared # If rSquared is > 0, calculate the force.
# Otherwise, the force is zero
V+=m.cos(m.atan2(x,y))*f # Add the Y component of the force to V
H+=m.sin(m.atan2(x,y))*f # Add the X component of the force to H

d=m.atan2(V,H)
print(V**2+H**2)**.5,[d,m.pi*2+d][d<0]


Some little program used to create tests:

import Image
width  = 100 # Define your own image width
height = 100 # Define your own image height
image = Image.new("RGB", (width, height), "white")
blacks = [(0,0), (1,1)] # Define your own black pixels
reds   = [(0,1), (1,0)] # Define your own red pixels
for x,y in blacks:
pixels[x,height-1-y] = (0,0,0)
for x,y in reds:
pixels[x,height-1-y] = (255,0,0)
image.save("y.png") # Save image


Sample tests: Users-MacBook-Air:pngforces User$python z3.py y.png 0 0 59.3969696197 0.785398163397 Users-MacBook-Air:pngforces User$ python z3.py y.png 50 50
0.0084 3.92699081699 Users-MacBook-Air:pngforces User\$ python z3.py y.png 50 50
0.0084 0.785398163397


Just posting first... If there are any mistakes or issues, drop a comment down below, but will probably take quite some time to respond cuz I am really busy with other stuff.

• I love the test program! It's a lot better than zooming in 400% on a little image, making dots by hand, then trying to record the locations of all the little dots. You must be a programmer! – Rainbolt Aug 30 '14 at 18:24