Question

Tout d’abord, je suis assez sûr que l’accès à la grille est assez facile, mais j’ai rencontré quelques problèmes étranges dans cette situation et mes calculs sont trop faibles pour déterminer précisément ce qui ne va pas.

Voici la situation

J'ai un concept abstrait de grille, avec Y pas à pas exactement Y_STEP (les pas x fonctionnent correctement, alors ignorez-les pour l'instant)

La grille est dans un espace de coordonnées abstrait, et pour aligner les choses, il existe un décalage magique, appelons-le Y_OFFSET

pour accrocher à la grille, j'ai le code suivant (python)

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

donc je passe la position du curseur, Y_OFFSET et Y_STEP dans cette fonction et il me renvoie la position y la plus proche sur la grille

Cela semble bien fonctionner dans le scénario d'origine, mais lorsque je prends en compte le fait que la vue est défilante, les choses deviennent un peu bizarres.

Le défilement est aussi élémentaire que possible, j'ai un viewPort qui comptabilise la distance parcourue le long de l'axe Y et compense simplement tout ce qui le traverse.

Voici un extrait du code mouseMotion du curseur:

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

Il y a donc deux choses à regarder ici, tout d'abord la conversion du module Scroll de la position du pixel en l'espace de coordonnées abstraites, puis la fonction positionChanged de l'outil qui prend la valeur de l'espace de coordonnées abstraites et s'accroche au pas Y le plus proche.

Voici le code de défilement approprié

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

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

Et le code de mise à jour des outils

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

Le dernier bloc pertinent est celui où l'outil va se rendre lui-même. Il passe par l'objet Scroll, qui transforme la position de l'espace de coordonnées capturé de l'outil en une position de pixel à l'écran. Voici le code:

#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)

Ouf, c'était une longue explication. J'espère que tu es toujours avec moi ...

Le problème que je vois maintenant, c’est que lorsque je fais défiler vers le haut l’image dessinée perd son alignement avec le curseur.
Il commence à accrocher à l'étape Y exactement 1 étape sous le curseur. En outre, il semble procéder à des ajustements progressifs.
À certains parchemins, il est sorti par 1 et d'autres parchemins, il est sur place.
Elle n’est jamais dépassée par plus de 1 et est toujours capturée par un emplacement de grille valide.

La meilleure hypothèse que je puisse en venir est que quelque part, je tronque certaines données au mauvais endroit, mais je ne sais pas où ni comment cela se termine avec ce comportement.

Quelqu'un qui est familier avec les espaces de coordonnées, le défilement et la capture?

Était-ce utile?

La solution

D'accord, je réponds à ma propre question ici, comme l'a mentionné Alexk, utiliser int pour tronquer était mon erreur.

Le comportement que je recherche est mieux modélisé par math.floor ().

Toutes mes excuses, la question initiale ne contient pas assez d'informations pour vraiment cerner le problème. Je n'avais pas le peu d'informations supplémentaires à ce moment-là.

En ce qui concerne la note de frappe, je pense que j'utilise peut-être le contexte de façon confuse ... Du point de vue de la fonction positionChanged (), le paramètre est une nouvelle position à venir.
Du point de vue de la fonction snapToGrid (), le paramètre est une position d'origine en cours de modification. La langue est comme ça parce qu’une partie est dans mon code de gestion d’événement et l’autre partie est dans mon code de services généraux. J'aurais dû le changer pour l'exemple

Autres conseils

Avez-vous une faute de frappe dans positionChanged ()?

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

Je suppose que vous êtes décalé d’un pixel en raison des problèmes de précision rencontrés lors de la division du flottant. Essayez de changer votre snapToGrid () en ceci:

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

Merci pour la réponse, il y a peut-être une faute de frappe, mais je ne la vois pas ...

Malheureusement, le changement apporté à snapToGrid n'a pas changé grand-chose, donc je ne pense pas que ce soit le problème.

Ce n’est pas désactivé d’un pixel, mais bien de Y_STEP. En jouant encore avec cela, je me suis rendu compte que je ne pouvais pas dire exactement à quel point l’écran est défilé et aussi que cela se produit en haut de l’écran, ce qui, je le soupçonne, correspond à la position zéro de la position EAD, Je suppose que mon problème concerne les valeurs faibles ou négatives.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top