Domanda

Prima di tutto, sono abbastanza sicuro che lo snap alla griglia sia abbastanza facile, tuttavia ho riscontrato alcuni strani problemi in questa situazione e i miei calcoli sono troppo deboli per capire in modo specifico cosa non va.

Ecco la situazione

Ho un concetto astratto di griglia, con Y passi esattamente Y_STEP a parte (i x passi stanno funzionando bene quindi ignorali per ora)

La griglia è in uno spazio di coordinate astratto e per allineare le cose ho un offset magico, chiamiamolo Y_OFFSET

per agganciare alla griglia ho il seguente codice (python)

def snapToGrid(originalPos, offset, step):
    index = int((originalPos - offset) / step) #truncates the remainder away
    return index * gap + offset

quindi passo la posizione del cursore, Y_OFFSET e Y_STEP in quella funzione e mi restituisce la posizione y con il pavimento più vicino sulla griglia

Ciò sembra funzionare bene nello scenario originale, tuttavia quando tengo conto del fatto che la vista è scorrevole le cose diventano un po 'strane.

Lo scorrimento è reso il più semplice possibile, ho un viewPort che tiene conto della distanza percorsa lungo l'asse Y e compensa tutto ciò che lo attraversa.

Ecco uno snippet del codice mouseMotion del cursore:

def mouseMotion(self, event):
    pixelPos = event.pos[Y]
    odePos = Scroll.pixelPosToOdePos(pixelPos)
    self.tool.positionChanged(odePos)

Quindi ci sono due cose da guardare lì, prima la traduzione del modulo Scroll dalla posizione dei pixel allo spazio delle coordinate astratte, quindi la funzione di posizione modificata dello strumento che prende il valore dello spazio delle coordinate astratte e si aggancia al passo Y più vicino.

Ecco il codice di scorrimento pertinente

def pixelPosToOdePos(pixelPos):
    offsetPixelPos = pixelPos - self.viewPortOffset
    return pixelsToOde(offsetPixelPos)

def pixelsToOde(pixels):
    return float(pixels) / float(pixels_in_an_ode_unit)

E il codice di aggiornamento degli strumenti

def positionChanged(self, newPos):
    self.snappedPos = snapToGrid(originalPos, Y_OFFSET, Y_STEP)

L'ultimo pezzo rilevante è quando lo strumento va a renderizzarsi. Passa attraverso l'oggetto Scroll, che trasforma la posizione dello spazio delle coordinate scattate dello strumento in una posizione di pixel sullo schermo, ecco il codice:

#in Tool
def render(self, screen):
    Scroll.render(screen, self.image, self.snappedPos)

#in Scroll
def render(self, screen, image, odePos):
    pixelPos = self.odePosToPixelPos(odePos)
    screen.blit(image, pixelPos) # screen is a surface from pygame for the curious

def odePosToPixelPos(self.odePos):
    offsetPos = odePos + self.viewPortOffset
    return odeToPixels(offsetPos)

def odeToPixels(odeUnits):
    return int(odeUnits * pixels_in_an_ode_unit)

Accidenti, questa è stata una lunga spiegazione. Spero che tu sia ancora con me ...

Il problema che sto ricevendo ora è che quando scorro verso l'alto l'immagine disegnata perde l'allineamento con il cursore.
Inizia a scattare sul passaggio Y esattamente 1 passo sotto il cursore. Inoltre sembra entrare e uscire gradualmente dall'allineamento.
In alcuni rotoli è fuori di 1 e altri rotoli è perfetto.
Non è mai uscito da più di 1 e si attacca sempre a una posizione della griglia valida.

La migliore ipotesi che posso inventare è che da qualche parte sto troncando alcuni dati nel posto sbagliato, ma non ho idea di dove o come finisca con questo comportamento.

Chiunque abbia familiarità con gli spazi delle coordinate, lo scorrimento e lo snap?

È stato utile?

Soluzione

Ok, sto rispondendo alla mia domanda qui, come ha detto Alexk, usare int per troncare è stato un mio errore.

Il comportamento che sto cercando è meglio modellato da math.floor ().

Ci scusiamo, la domanda originale non contiene abbastanza informazioni per capire quale sia il problema. Non avevo informazioni extra a quel punto.

Per quanto riguarda la nota di errore di battitura, penso che potrei usare il contesto in modo confuso ... Dal punto di vista della funzione positionChanged (), il parametro è una nuova posizione in arrivo.
Dal punto di vista della funzione snapToGrid () il parametro è una posizione originale che viene modificata in una posizione scattata. La lingua è così perché una parte è nel mio codice di gestione degli eventi e l'altra parte è nel mio codice di servizi generali. Avrei dovuto cambiarlo per l'esempio

Altri suggerimenti

Hai un refuso in positionChanged ()?

def positionChanged(self, newPos):
    self.snappedPos = snapToGrid(newPos, Y_OFFSET, Y_STEP)

Suppongo che tu sia spento di un pixel a causa dei problemi di precisione durante la divisione float. Prova a cambiare snapToGrid () in questo:

def snapToGrid(originalPos, offset, step):
    EPS = 1e-6
    index = int((originalPos - offset) / step  + EPS) #truncates the remainder away
    return index * gap + offset

Grazie per la risposta, potrebbe esserci un errore di battitura, ma non riesco a vederlo ...

Sfortunatamente la modifica a snapToGrid non ha fatto la differenza, quindi non credo che sia questo il problema.

Non è disattivato di un pixel, ma piuttosto è disattivato da Y_STEP. Giocandoci ancora un po ', ho scoperto che non riesco a renderlo esatto in nessun punto dello schermo verso l'alto e anche che accade verso la parte superiore dello schermo, che sospetto sia la posizione ODE zero, quindi Immagino che il mio problema riguardi valori piccoli o negativi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top