8
\$\begingroup\$

enter image description here

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
  • 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

enter image description here

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.

\$\endgroup\$
  • \$\begingroup\$ Can it be PPM instead of PNG? and typically, images put 0,0 in top left corner, do we have to rotate it? \$\endgroup\$ – user137 Aug 29 '14 at 15:27
  • \$\begingroup\$ @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? \$\endgroup\$ – Rainbolt Aug 29 '14 at 15:33
  • 2
    \$\begingroup\$ I love the intro picture... \$\endgroup\$ – trichoplax Aug 29 '14 at 17:28
  • \$\begingroup\$ 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. \$\endgroup\$ – tomsmeding Aug 30 '14 at 9:40
  • \$\begingroup\$ 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) ? \$\endgroup\$ – Vectorized Aug 30 '14 at 15:47
2
\$\begingroup\$

Python - 355

import sys,Image,math as m
i=Image.open(sys.argv[1])
w,h=i.size
a=i.load()
X,Y=map(int,sys.argv[2:])
t=m.atan2
c=lambda i,j:2*(a[i,j][0]>200)-(a[i,j][1]>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[1]) # 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][0]>200: # If Red > 200
        if a[i,j][2]>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")
pixels = image.load()
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:

enter image description here

Users-MacBook-Air:pngforces User$ python z3.py y.png 0 0
59.3969696197 0.785398163397

enter image description here

Users-MacBook-Air:pngforces User$ python z3.py y.png 50 50
0.0084 3.92699081699

enter image description here

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.

\$\endgroup\$
  • 2
    \$\begingroup\$ 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! \$\endgroup\$ – Rainbolt Aug 30 '14 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.