I have a source image (arbitrary width and height c) shown here as a rectangle [X1,X2,X3,X4]. It contains two points C and D (both known coordinates within the image - X4 / top left).

Source image

Then I have a target image (might have different height a and width b than source image) that contains two points A and B (|AB| doesn't necessarily equal |CD|). There's also a source of projection S.

Target image

I need to somehow calculate coordinates of a transformed rectangle (polygon) such that:

  1. Point C will always be mapped to A (therefore A will be equal to C) and D will be mapped to B (B = D)
  2. Point X3 of this newly calculated polygon will lie on a line between S and A/C (now identical)
  3. Point X4 will lie on a line from S to B/D.
  4. Distance from parallel lines [X1,X2] and [X3,X4] will be still c. (If it turns out that it's not always possible to construct such a polygon the condition 4. can be dropped, and [X1,X2] don't need to be parallel to [X3,X4] as well)

(see below)

Result image

What I've tried

I thought I will solve it by:

  1. shrinking width of source image by ratio of |AB| and |CD|
  2. aligning C with A (move source image)
  3. finding angle difference 𝛼 between AB and CD
  4. rotating source image by angle 𝛼 (with center in C/A)
  5. calculating X3 and X4

But it doesn't work universally. Steps 1-4 work well, but then changing X3 and X4 moves C (resp. D) away from A (resp. B).

  • \$\begingroup\$ Can you give us some context of what's motivating these geometric transformations? It looks like we might be doing some kind of perspective matching/correction, but knowing the details could remove ambiguity or even open the door to known solutions for that particular application. \$\endgroup\$
    – DMGregory
    Jan 29, 2019 at 3:51
  • \$\begingroup\$ It's casting a shadow in a 2D isometric game. I have images (sprites) for 8 directions of "rotation". By itself they're used just plainly as a sprite, but then depending on light direction I determine the best direction of "shadow" I turn pixels to black and cast this shadow to a polygon created by "3D" cone from 3D light position. I know height (c) of the entity. It works well for entities having one ground point (like a person or a column). I'm trying to generalize algorithm for things with 2 or more points. I figured out I need to match nearest 2 ground points (imagine a bench for example). \$\endgroup\$
    – SmartK8
    Jan 29, 2019 at 8:22
  • \$\begingroup\$ So target image is sprite to be drawn and source image is a different rotation of this sprite (usually the same width and height, but not always) used as a shadow. Result is a polygon of - to be cast - shadow. It's not precise shadow of course, but it works reasonably well (at least for one point), but I tried drawing it (manually) and it looks OK for two points as well. Thus this question. \$\endgroup\$
    – SmartK8
    Jan 29, 2019 at 8:31
  • \$\begingroup\$ Can we make some assumptions about the setup of your shadow image - eg. that points C & D are at the same height, and equally spaced left & right from the center of the quad? (This would put the pre-image of S on the center line, at a fixed height below the bottom of the image). For full generality we might sometimes need to skew/shear the image - is that supported in your case? \$\endgroup\$
    – DMGregory
    Jan 29, 2019 at 13:35
  • \$\begingroup\$ For me the shadow is just quad so any transformation is possible skew/shear or any other. For me it is a free transform polygon basically. It doesn't even have to be transform per se (if the points are somehow magically calculated). 'c' and 'd' are just height (c = X2.y - X3.y) and width of source image as well as 'a' and 'b' are just height and width of target image. I marked them to denote that 'a' and 'c' can be different and 'b' and 'd' as well. \$\endgroup\$
    – SmartK8
    Jan 29, 2019 at 14:01


You must log in to answer this question.

Browse other questions tagged .