オリジナル合成ソフト開発でレイヤー選択機能を実装しました。この機能実装で面倒なことはレイヤーがトランスフォームされているということです。どうするのが一番簡単かなと考えた結果、クリックした座標における一番上のトランスフォームされたレイヤーを探すために、ある座標があるレイヤーの上にあるかどうかを逆アフィン変換を使って判定していくのが楽かなという結論に至りました。実装したC++関数の大まかなソースコードを載せておきます。
struct AffineParam{
float anchor_pt_x, anchor_pt_y;
float translate_x, translate_y;
float scale_x, scale_y;
float rotate_angle;
};
inline bool IsOnLayer( int x, int y, int width, int height, const AffineParam ¶m )
{
float centered_x, centered_y;
int src_x, src_y;
float rotate_rad = param.rotate_angle * PI / 180.0f;
float sx_mult = 1.0f / param.scale_x;
float sy_mult = 1.0f / param.scale_y;
float tx = param.translate_x;
float ty = param.translate_y;
float ax = param.anchor_pt_x + tx;
float ay = param.anchor_pt_y + ty;
centered_x = x - ax;
centered_y = y - ay;
src_x = (int)( (centered_x * cos(rotate_rad) - centered_y * sin(rotate_rad)) * sx_mult - tx + ax );
src_y = (int)( (centered_x * sin(rotate_rad) + centered_y * cos(rotate_rad)) * sy_mult - ty + ay );
return 0<=src_x&& src_x<width&& 0<=src_y&& src_y<height;
}
複数レイヤーを上から順番に見てゆき、この関数でそれぞれのレイヤー上にカーソルがのっているかどうかを判定し、最初にtrueとなったレイヤーを選択されるレイヤーとして選ぶようにします。