アプリの要素に適用する変換の正しい順序を理解するのに苦労しています。アプリには親子関係を持つ要素があり、各要素には変換があります (各要素はローカル空間に描画されてから変換されます)。
私がアーカイブしたいのは、親を変換すると、そのすべての子も変換される必要があることです(したがって、親を回転させると、子は親の周りを回転する必要があります)。
以下のコードはまさにそれを行いますが、問題は親を回転させてから子を移動したい場合です。間違った方向に移動します (親の変換のため)。変換のシーケンスを変更しようとしましたが、うまくいきませんでした (最初に変換してから変換する必要があることはわかっていますが、その後、子は親ではなく独自の軸を中心に回転します)。
コード:
Element e;
AffineTransform t = new AffineTransform();
AffineTransform t3 = new AffineTransform();
for (i = 0; i < el.size(); i++)
{
e = el.get(i);
t3.setToIdentity();
t.setToIdentity();
tmp = e.getParent();
while(tmp != null)
{
t.translate(tmp.getX(), tmp.getY());
t3.rotate(Math.toRadians(tmp.getAngle()),tmp.getAnchorX(), tmp.getAnchorY());
tmp = tmp.getParent();
}
t.concatenate(t3);
t.translate(e.getX(), e.getY());
t.rotate(Math.toRadians(e.getAngle()),e.getAnchorX(), e.getAnchorY());
e.draw(g2d,t);
}
問題: - 2 つの要素 (他の 1 つの子) が与えられた場合 - 親が回転 (40 度) - 子が 10px 移動 子を移動したときに回転方向に移動しないように変換を連結するにはどうすればよいですか?
編集: Torious が投稿したコード (まだ動作していません):
public AffineTransform getTransformTo(Element ancestor) {
AffineTransform t = (AffineTransform)getAffineTransform().clone();
Element parent = getParent();
while (parent != null && parent != ancestor) {
t.preConcatenate(parent.getAffineTransform());
parent = parent.getParent();
}
return t;
}
public void translateInAncestorSpace(Element ancestor, Point translation) {
AffineTransform fromAncestor = getTransformTo(ancestor); // to ancestor space
try
{
fromAncestor.invert();
} catch(Exception e)
{
e.printStackTrace();
}
translation = (Point)fromAncestor.transform(translation, new Point());
Transform t1 = new Transform();
t1.translate(translation.x,translation.y);
transform(t1);
}
コードの出力:
Moving by [x=1,y=1] old position [x=22,y=40]
Moved by [x=-21,y=-39] new position [x=1,y=1]
Moving by [x=2,y=2] old position [x=1,y=1]
Moved by [x=1,y=1] new position [x=2,y=2]
Moving by [x=4,y=3] old position [x=2,y=2]
Moved by [x=2,y=1] new position [x=4,y=3]