Fuerzas de píxeles PNG

8

ingrese la descripción de la imagen aquí

Desafío

Un mundo de píxeles es una imagen PNG donde las fuerzas gravitacionales, electromagnéticas y nucleares ya no existen. Las fuerzas especiales conocidas como "fuerzas de píxeles" son todo lo que queda. Definimos esta fuerza como

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

  • Fes la fuerza de píxeles que pejerce sobreq
  • a es la constante de Adams, definida como a = 4.2 * 10 ^ 1
  • py qson cargos en dos píxeles
  • res la distancia desde phastaq
  • es la dirección de r en radianes, medida en sentido antihorario * desde el eje x positivo

* Hay infinitos valores aceptables para cualquier dirección dada. Por ejemplo, 6.28, 0, -6.28 y -12.57 radianes son todos equivalentes, y todos serían aceptados.

Existen tres tipos de píxeles:

  • Un píxel rojo tiene una carga positiva.
  • Un píxel negro tiene una carga negativa.
  • Un píxel blanco tiene una carga de cero

El píxel inferior izquierdo del mundo de píxeles se encuentra en (0, 0). El eje y positivo cae en la página, y el eje x positivo cae a la derecha. La fuerza total sobre un píxel es simplemente la suma vectorial de todas las fuerzas ejercidas sobre ese píxel. Los cargos similares se repelen y los cargos opuestos se atraen.

Dada una ruta de archivo a Pixel World, así como dos enteros xy y, genera la fuerza total ejercida sobre el píxel en la ubicación (x, y)en el formato <magnitude>\n<direction>. La salida debe tener una precisión de al menos 2 decimales, pero puede generar más si lo desea. La dirección debe salir en radianes. Los enteros xy yestán garantizados para estar dentro de los límites del mundo.

Entregables

Debe incluir un programa y un comando que pueda usarse para ejecutar su programa. Dos ejemplos:

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

Imagen de ejemplo

En la imagen a continuación , hay un píxel negro en (100, 104).

Pixars.png

ingrese la descripción de la imagen aquí

Salida de ejemplo

Esta salida no corresponde a la entrada anterior.

534.19721014
4.32605416

¿Necesita ayuda para comenzar?

Escribí un código de ejemplo aquí . No lo he probado, así que úselo bajo su propio riesgo.

Perno de lluvia
fuente
¿Puede ser PPM en lugar de PNG? y típicamente, las imágenes ponen 0,0 en la esquina superior izquierda, ¿tenemos que rotarlo?
usuario137
@ user137 Todos deben manejar el formato de imagen PNG. Estoy considerando publicar un código Java para que la gente comience. No quiero comenzar a agregar requisitos opcionales. La parte inferior izquierda se seleccionó como (0,0) porque esto nos permite usar un sistema de coordenadas a la derecha y medir radianes en sentido antihorario desde el eje x positivo. Si colocamos (0,0) en la parte superior izquierda, y los radianes se medirían en sentido horario desde el eje x positivo. No importa de qué manera lo haga, desafortunadamente se romperá algún estándar. ¿No podrías voltear la imagen de todos modos?
Rainbolt
2
Me encanta la imagen de introducción ...
trichoplax
Creo que la opción para PNG realmente detendrá a las personas, excepto aquellas que tengan conocimiento de Java, que, hasta donde yo sé, es el único lenguaje con algo como ImageIO. C ++, por ejemplo, no lo tiene.
tomsmeding
Buen desafío PNG está bien IMO. Por cierto, aquí hay algunas preguntas que tengo al intentarlo. 1. No estoy seguro de si soy yo, pero parece que no puedo encontrar el píxel negro en (99,101) en la imagen. 2. ¿El ejemplo muestra la respuesta para la imagen de prueba? 3. Para la dirección, si el ángulo es <pi grados en el sentido de las agujas del reloj desde el eje + ve x, ¿se permiten valores negativos (es decir, 0 <Ángulo <pi), o debe serlo (pi <Ángulo <2 * pi)?
Vectorizado el

Respuestas:

2

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]

Sin golf

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]

Algún pequeño programa utilizado para crear pruebas:

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

Pruebas de muestra:

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

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

Solo publique primero ... Si hay algún error o problema, deje un comentario a continuación, pero probablemente me tomará bastante tiempo responder porque estoy realmente ocupado con otras cosas.

Vectorizado
fuente
2
¡Me encanta el programa de prueba! Es mucho mejor que hacer un zoom del 400% en una pequeña imagen, hacer puntos a mano y luego intentar registrar las ubicaciones de todos los pequeños puntos. ¡Debes ser un programador!
Rainbolt