Perspective and bilinear transformations

I am making a vector drawing application and noticed that there is an example in Anti Grain Geometry that does exactly what I want. http://www.antigrain.com/demo/index.html , below is an example of a perspective for Win32. I do not understand their cpp file. Based on this example. If I have a bunch of vertices to form an object, like their lion, and then I have 4 vertices as control points, how can I achieve their effect? Ex, what transformation do I apply to each point?

thanks

+2
source share
2 answers

From the same page that you published, there is a link to the source code. I will explain the bilinear conversion to

http://www.antigrain.com/__code/include/agg_trans_bilinear.h.html

The idea here is to find a shape transform:

output_x = a * input_x + b * input_x * input_y + c * input_y + d output_y = e * input_x + f * input_x * input_y + g * input_y + h 

The term "bilinear" comes from each of these equations, linear in either of the input coordinates. We want to solve the correct values ​​of a, b, c and d. Let's say you have a link rectangle r1, r2, r3, r4 that you want to display on (0,0), (1,0), (0,1), (1,1) (or some image coordinate system) .

For a, b, c, d:

 0 = a * r1_x + b * r1_x * r1_y + c * r1_y + d 1 = a * r2_x + b * r2_x * r2_y + c * r2_y + d 0 = a * r3_x + b * r3_x * r3_y + c * r3_y + d 1 = a * r4_x + b * r4_x * r4_y + c * r4_y + d 

For e, f, g, h:

 0 = e * r1_x + f * r1_x * r1_y + g * r1_y + h 0 = e * r2_x + f * r2_x * r2_y + g * r2_y + h 1 = e * r3_x + f * r3_x * r3_y + g * r3_y + h 1 = e * r4_x + f * r4_x * r4_y + g * r4_y + h 

You can solve it, but you like it most. (If you are familiar with matrix notation, these are two matrix equations for which the matrix is ​​the same, and then you just need to find the LU decomposition once and solve two unknown vectors). Then the coefficients are used to map the inside of the rectangle to a position in the rectangle.

If you accidentally look for the inverse transform, that is, if you want to know where this pixel will be located, you simply switch the inputs and outputs:

For a, b, c, d:

 r1_x = a * 0 + b * 0 * 0 + c * 0 + d r2_x = a * 1 + b * 1 * 0 + c * 0 + d r3_x = a * 0 + b * 0 * 1 + c * 1 + d r4_x = a * 1 + b * 1 * 1 + c * 1 + d 

For e, f, g, h:

 r1_y = e * 0 + f * 0 * 0 + g * 0 + h r2_y = e * 1 + f * 1 * 0 + g * 0 + h r3_y = e * 0 + f * 0 * 1 + g * 1 + h r4_y = e * 0 + f * 0 * 1 + g * 1 + h 
+1
source

You are talking about transforming perspectives from a 2D planar into a square “in space”, I think.

Good. It is not that difficult. Mathematics is explained in the article:

Huckert, Paul, Fundamentals of Texture mapping and image warping, Master's thesis, UCB / CSD 89/516, CS Division, UC Berkeley, June 1989.

(I do not refer to the document for copyright reasons. It is available on the network and you should not have problems finding it)

This gives you math, and some are willing to use equations for this.

If you are looking for some “easy-to-copy” code, I suggest downloading the reference OpenVG implementation and carefully looking at the functions “vguComputeWarpQuadToSquare”, “vguComputeWarpSquareToQuad” and “vguComputeWarpQuadToQuad” :-) They cover everything you need.

Download here: http://www.khronos.org/registry/vg/ri/openvg-1.1-ri.zip

These functions will calculate a 3x3 matrix that performs the conversion. To use this matrix, you must extend the 2D coordinates into two-dimensional uniform coordinates. This is not so difficult, but is beyond the scope of the question. If you need help working with them, I suggest you ask another question.

+1
source

All Articles