2010-04-29 5 views
1

J'ai une image (i) qui a été mise à l'échelle de sa taille d'origine (rectLarge) pour s'adapter à un rectangle plus petit (rectSmall). Étant donné un point p dans rectSmall, comment puis-je traduire ceci en un point dans rectLarge.Comment traduire un point d'un rect à un point d'un rect scalé?

Pour faire ce béton, supposons que j'ai une image de 20x20 qui a été mis à l'échelle à un rect 10x10. Le point (1, 1) dans le rectangle le plus petit doit être mis à l'échelle jusqu'à un point du rectangle le plus grand (c.-à-d. (2,2)).

Je suis en train d'y parvenir avec:

result.x = point.x * (destRect.size.width/srcRect.size.width); 
result.y = point.y * (destRect.size.height/srcRect.size.height); 

Cependant, les points générés par ce code ne sont pas correctes - ils ne correspondent pas au point approprié dans l'image originale. Qu'est-ce que je fais mal?

+0

En quoi ces points ne sont-ils pas positionnés correctement? Gardez à l'esprit que la mise à l'échelle d'autres valeurs que les multiplications du plus grand dénominateur commun peut produire des valeurs non-entières dans la division et des sortes d'arrondis. –

+0

Gabriel, j'ai donné quelques explications supplémentaires en réponse à la réponse de Jacob ci-dessous. – Bill

+0

Pouvez-vous donner quelques exemples de tailles qui donnent des résultats incorrects? destRect.size, srcRect.size, point, et le résultat, afin que nous puissions mieux l'aider à le déboguer? – clahey

Répondre

0

Quel est le "point approprié"? Si la taille de srcRect est supérieure à destRect alors votre code est correct. En outre, ne pas oublier que result.x et result.y sera un nombre à virgule flottante et de les utiliser dans l'image que vous devez arrondir ou faire une interpolation bilinéaire, etc. Avant, je peux donner une réponse plus détaillée, ce que vous allez faire avec result?

+0

Pour élaborer un peu, j'ai une image qui est légèrement plus grande que l'écran disponible. L'image est légèrement réduite pour un mode "Aperçu" où l'utilisateur clique sur un point pour indiquer une région. J'ai besoin de traduire ce point du rectangle de l'image d'aperçu à l'image originale afin de traiter la région. srcRect est plus grand que destRect. – Bill

0

Je suppose que le problème est que votre rectangle n'est pas positionné à (0, 0) et, par conséquent, vous ne pouvez pas mettre à l'échelle tous les points à l'intérieur de celui-ci de la même manière que ses dimensions.

Vous devrez déterminer le décalage d'un point d'ancrage dans votre rectangle (par exemple, point supérieur gauche), votre point résultant serait anchor_point.x + offset.x * (horizontal_scale_ratio) et même pour y (avec vertical_scale_ratio).

rapports il y a new_width/old_width et new_height/old_height.

+0

(point.x, point.y) est relatif à la partie supérieure gauche du plus petit rectangle. – Bill

+0

Ensuite, je pense que votre problème est soit dans un autre endroit ou comme ça. Le morceau de code que vous avez posté semble bon et je ne soupçonne aucun problème. –

1

Quelle langue utilisez-vous?

Si cela est C, et rect.size.height et similaires sont ints, alors vous avez un problème d'arrondi majeur. Supposons que vous soyez à l'échelle 10, 10 à partir d'une taille 20x20 jusqu'à revenir à une taille 30x30. Vos calculs ressemblera:

result.x = 10 * (30/20); 

Cela simplifie à:

result.x = 10 * (1); 

La façon la plus simple de résoudre ce problème est de se débarrasser des parenthèses:

result.x = point.x * destRect.size.width/srcRect.size.width; 
result.y = point.y * destRect.size.height/srcRect.size.height; 

Maintenant votre calcul, 10 * 30/20 , simplifie à 300/20, puis à 15, ce qui est ce que vous voulez. Notez que vous avez toujours un léger problème d'arrondi, mais à moins que vous ne puissiez obtenir des emplacements de sous-pixel, c'est à peu près aussi proche que vous l'obtiendrez.

+0

Objective-C, donc les règles C arithmétiques s'appliquent. Ces valeurs sont toutes flottantes. – Bill

Questions connexes