PNG Pixel Forces

8

Geben Sie hier die Bildbeschreibung ein

Herausforderung

Eine Pixelwelt ist ein PNG-Bild, in dem Gravitations-, elektromagnetische und nukleare Kräfte nicht mehr existieren. Es bleiben nur Spezialkräfte, die als "Pixelkräfte" bekannt sind. Wir definieren diese Kraft als

F p → q = a * (p * q) / (r * r) * r̂

  • Fist die Pixelkraft, die pausgeübt wirdq
  • a ist Adams 'Konstante, definiert als a = 4.2 * 10 ^ 1
  • pund qsind Ladungen auf zwei Pixeln
  • rist die Entfernung von pbisq
  • ist die Richtung von r im Bogenmaß, gemessen gegen den Uhrzeigersinn * von der positiven x-Achse

* Es gibt unendlich viele akzeptable Werte für eine bestimmte Richtung. Zum Beispiel sind 6,28, 0, -6,28 und -12,57 Bogenmaß alle äquivalent und würden alle akzeptiert.

Es gibt drei Arten von Pixeln:

  • Ein rotes Pixel enthält eine positive Ladung
  • Ein schwarzes Pixel enthält eine negative Ladung
  • Ein weißes Pixel enthält eine Ladung von Null

Das untere linke Pixel der Pixelwelt befindet sich bei (0, 0). Die positive y-Achse fällt auf der Seite nach oben und die positive x-Achse fällt nach rechts. Die Gesamtkraft auf ein Pixel ist einfach die Vektorsumme aller auf dieses Pixel ausgeübten Kräfte. Wie Ladungen abstoßen und entgegengesetzte Ladungen anziehen.

Bei einem Dateipfad zu einer Pixelwelt sowie zwei Ganzzahlen xund ywird die Gesamtkraft ausgegeben, die auf das Pixel an der Stelle (x, y)im Format ausgeübt wird <magnitude>\n<direction>. Die Ausgabe muss auf mindestens 2 Dezimalstellen genau sein. Sie können jedoch auch mehr ausgeben, wenn Sie möchten. Die Richtung muss im Bogenmaß ausgegeben werden. Die ganzen Zahlen xund ysind garantiert innerhalb der Weltgrenze.

Ergebnisse

Sie müssen ein Programm und einen Befehl einschließen, mit dem Sie Ihr Programm ausführen können. Zwei Beispiele:

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

Beispielbild

Im Bild unten befindet sich ein schwarzes Pixel bei (100, 104).

Pixars.png

Geben Sie hier die Bildbeschreibung ein

Beispielausgabe

Diese Ausgabe entspricht nicht der obigen Eingabe.

534.19721014
4.32605416

Benötigen Sie Hilfe beim Einstieg?

Ich schrieb einige Beispiel - Code hier . Ich habe es nicht getestet, benutze es also auf eigenes Risiko.

Regenblitz
quelle
Kann es PPM statt PNG sein? und normalerweise setzen Bilder 0,0 in die obere linke Ecke. Müssen wir sie drehen?
user137
@ user137 Jeder muss mit dem PNG-Bildformat umgehen. Ich denke darüber nach, Java-Code zu veröffentlichen, um die Leute zum Laufen zu bringen. Ich möchte keine optionalen Anforderungen hinzufügen. Die untere linke Ecke wurde als (0,0) ausgewählt, da dies die Verwendung eines rechten Koordinatensystems und das Messen des Bogenmaßes von der positiven x-Achse gegen den Uhrzeigersinn ermöglicht. Wenn wir (0,0) oben links platzieren und das Bogenmaß von der positiven x-Achse im Uhrzeigersinn gemessen wird. Egal wie Sie es machen, einige Standards werden leider gebrochen. Könnten Sie das Bild nicht einfach umdrehen?
Rainbolt
2
Ich liebe das Intro-Bild ...
Trichoplax
Ich denke, die Wahl für PNG wird die Leute wirklich zurückhalten, außer denen mit guten Java-Kenntnissen - die meines Wissens die einzige Sprache mit so etwas wie ImageIO sind. Zum einen hat C ++ es nicht.
Tomsmeding
Schöne Herausforderung. PNG ist in Ordnung IMO. Übrigens, hier sind einige Fragen, die ich beim Versuch habe. 1. Ich bin nicht sicher, ob ich es bin, aber ich kann das schwarze Pixel in (99.101) im Bild nicht finden. 2. Ist die Beispielausgabe die Antwort für das Testbild? 3. Wenn für die Richtung <pi Grad im Uhrzeigersinn von der + ve x-Achse <pi Grad ist, sind negative Werte (dh 0 <Winkel <pi) zulässig oder müssen sie sein (pi <Winkel <2 * pi)?
Vektorisiert

Antworten:

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]

Ein kleines Programm zum Erstellen von 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

Beispieltests:

Geben Sie hier die Bildbeschreibung ein

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

Geben Sie hier die Bildbeschreibung ein

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

Geben Sie hier die Bildbeschreibung ein

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

Nur zuerst posten ... Wenn es Fehler oder Probleme gibt, schreiben Sie unten einen Kommentar, aber es wird wahrscheinlich einige Zeit dauern, bis Sie antworten, da ich wirklich mit anderen Dingen beschäftigt bin.

Vektorisiert
quelle
2
Ich liebe das Testprogramm! Es ist viel besser, als ein kleines Bild um 400% zu vergrößern, Punkte von Hand zu machen und dann zu versuchen, die Positionen aller kleinen Punkte aufzuzeichnen. Sie müssen ein Programmierer sein!
Rainbolt