Forças de pixel PNG

8

insira a descrição da imagem aqui

Desafio

Um Pixel World é uma imagem PNG onde as forças gravitacionais, eletromagnéticas e nucleares não existem mais. As forças especiais conhecidas como "forças de pixel" são tudo o que resta. Nós definimos essa força como

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

  • Fé a força do pixel que pexerce sobreq
  • a é constante de Adams, definida como a = 4.2 * 10 ^ 1
  • pe qsão cobranças em dois pixels
  • ré a distância de patéq
  • é a direção de r em radianos, medida no sentido anti-horário * a partir do eixo x positivo

* Existem infinitamente muitos valores aceitáveis ​​para qualquer direção. Por exemplo, 6.28, 0, -6.28 e -12.57 radianos são todos equivalentes e todos seriam aceitos.

Existem três tipos de pixels:

  • Um pixel vermelho contém uma carga de um positivo
  • Um pixel preto contém uma carga de um negativo
  • Um pixel branco mantém uma carga zero

O pixel inferior esquerdo do mundo de pixels está localizado em (0, 0). O eixo y positivo cai na página e o eixo x positivo cai para a direita. A força total em um pixel é simplesmente a soma vetorial de todas as forças exercidas sobre esse pixel. Cargas iguais se repelem, e cargas opostas se atraem.

Dado um caminho de arquivo para um mundo de pixels, bem como dois números inteiros xe y, produza a força total exercida no pixel no local (x, y)no formato <magnitude>\n<direction>. A saída deve ser precisa com pelo menos 2 casas decimais, mas você pode gerar mais, se desejar. A direção deve ser emitida em radianos. Os números inteiros xe ysão garantidos para estar dentro dos limites do mundo.

Entregas

Você deve incluir um programa e um comando que possa ser usado para executar seu programa. Dois exemplos:

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

Imagem de exemplo

Na imagem abaixo , há um pixel preto em (100, 104).

Pixars.png

insira a descrição da imagem aqui

Saída de exemplo

Esta saída não corresponde à entrada acima.

534.19721014
4.32605416

Precisa de ajuda para começar?

Eu escrevi algum código de exemplo aqui . Eu não testei, então use-o por sua conta e risco.

Rainbolt
fonte
Pode ser PPM em vez de PNG? e tipicamente, as imagens colocam 0,0 no canto superior esquerdo, precisamos rotacioná-lo?
user137
@ user137 Todo mundo tem que lidar com o formato de imagem PNG. Estou pensando em publicar algum código Java para ajudar as pessoas. Não quero começar a adicionar requisitos opcionais. O canto inferior esquerdo foi selecionado como (0,0) porque isso nos permite usar um sistema de coordenadas à direita e medir radianos no sentido anti-horário a partir do eixo x positivo. Se colocarmos (0,0) no canto superior esquerdo, e os radianos serão medidos no sentido horário a partir do eixo x positivo. Não importa como você o faça, infelizmente algum padrão será quebrado. Você não poderia simplesmente virar a imagem?
Rainbolt 29/08/14
2
Eu amo a imagem de introdução ...
Trichoplax
Eu acho que a escolha do PNG realmente impedirá as pessoas, exceto aquelas com conhecimento pronto de Java - que, até onde eu sei, é a única linguagem com algo como o ImageIO. C ++, por exemplo, não possui.
tomsmeding
Bom desafio. PNG é bom para IMO. Btw, aqui estão algumas perguntas que tenho ao tentar isso. 1. Não tenho certeza se sou eu, mas não consigo encontrar o pixel preto em (99.101) na imagem. 2. O exemplo de saída é a resposta para a imagem de teste? 3. Para a direção, se o ângulo for <pi graus no sentido horário a partir do eixo x + ve, os valores negativos (ie 0 <Ângulo <pi) são permitidos ou devem ser (pi <Ângulo <2 * pi)?
Vetorizado

Respostas:

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]

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]

Algum pequeno programa usado para criar testes:

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

Testes de amostra:

insira a descrição da imagem aqui

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

insira a descrição da imagem aqui

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

insira a descrição da imagem aqui

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

Apenas postando primeiro ... Se houver algum erro ou problema, deixe um comentário abaixo, mas provavelmente levará algum tempo para responder, porque eu estou realmente ocupado com outras coisas.

Vetorizado
fonte
2
Eu amo o programa de teste! É muito melhor do que aumentar o zoom em 400% em uma pequena imagem, criando pontos à mão e depois tentando gravar a localização de todos os pequenos pontos. Você deve ser um programador!
Rainbolt 30/08/14