Warning! Some information on this page is older than 5 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

Wed

23

Jan 2013

A class of 2D or 3D point and vector transformations called affine transformations (that is - linear transformation plus translation) can be conveniently represented by matrix. But sometimes we don't need possibility of input x to influence output y or vice versa. For example, that's the case when we want to convert coordinates of mouse cursor from pixels, like we take it from WinAPI (where X goes right from 0 to e.g. 1280 and Y goes down from 0 to e.g. 720) to post-projective 3D space (where X goes right from -1.0 to +1.0 and Y goes up from -1.0 on the bottom to +1.0 on the top). Then every component can be transformed independently using linear transform, like this:

Parameters are: scale.xy, bias.xy.

Given input point i.xy, output point o.xy is:

o.x = i.x * scale.x + bias.x

o.y = i.y * scale.y + bias.y

This seems trivial, but what if we wanted to encapsulate such transformation in a new data structure and define operations on it, like we do on matrices? Let's call it **SBX - Scale-Bias Transform**. I propose following structure:

struct ScaleBiasXform

{

static const ScaleBiasXform IDENTITY;

vec2 Scale;

vec2 Bias;

};

And following functions:

void Construct(ScaleBiasXform& out,

const vec2& input1, const vec2& output1,

const vec2& input2, const vec2& output2);

void Scaling(ScaleBiasXform& out, float scale);

void Scaling(ScaleBiasXform& out, const vec2& scale);

void Translation(ScaleBiasXform& out, const vec2& vec);

void Inverse(ScaleBiasXform& out, const ScaleBiasXform& sbx);

void Combine(ScaleBiasXform& out, const ScaleBiasXform& sbx1, const ScaleBiasXform& sbx2);

void TransformPoint(vec2& out, const vec2& point, const ScaleBiasXform& sbx);

void UntransformPoint(vec2& out, const vec2& point, const ScaleBiasXform& sbx);

void TransformVector(vec2& out, const vec2& vec, const ScaleBiasXform& sbx);

void UntransformVector(vec2& out, const vec2& vec, const ScaleBiasXform& sbx);

Full source code with additional comments and function bodies is here: **ScaleBiasTransform.hpp**, **ScaleBiasTransform.cpp**. Some additional notes:

- vec2 is obviously structure containing: float x, y;
- vec2 has some overloaded operators, including lhs*rhs and lhs/rhs, which perform per-component multiplication or division.
- common::CalcLinearFactors used in CPP file is function from my CommonLib, defined in Base.hpp.

Copyright © 2004-2021