Масштабирование/преобразование фигуры в заданный прямоугольник с использованием AffineTransform

Я пытаюсь масштабировать/перевести java.awt.Shape с помощью AffineTransform, чтобы нарисовать его в определенном ограничивающем прямоугольнике.

Кроме того, я хочу нарисовать его в области рисования с параметром «масштабирование».

Я пробовал различные конкатенации AffineTransform, но не смог найти правильную последовательность. Например, следующее решение было неправильным:

double zoom=(...);/* current zoom */
Rectangle2D viewRect=(...)/** the rectangle where we want to paint the shape */
Shape shape=(...)/* the original shape that should fit in the rectangle viewRect */
Rectangle2D bounds=shape.getBounds2D();

double ratioW=(viewRect.getWidth()/bounds.getWidth());
double ratioH=(viewRect.getHeight()/bounds.getHeight());


AffineTransform transforms[]=
    {
    AffineTransform.getScaleInstance(zoom, zoom),
    AffineTransform.getTranslateInstance(-bounds.getX(),-bounds.getY()),
    AffineTransform.getTranslateInstance(viewRect.getX(),viewRect.getY()),
    AffineTransform.getScaleInstance(ratioW, ratioH)
    };


AffineTransform tr=new AffineTransform();
for(int i=0;i< transforms.length;++i)
    {
    tr.concatenate(transforms[i]);
    }

Shape shape2=tr.createTransformedShape(shape);
graphics2D.draw(shape2);

Любая идея о правильном AffineTransform ?

Большое спасибо

Пьер


person Pierre    schedule 01.10.2010    source источник


Ответы (2)


Обратите внимание, что преобразования AffineTransform "сцеплены". наиболее часто используемым способом", который может рассматриваться как последний в, первый ушел. Эффект можно увидеть в этом примере. Учитывая приведенную ниже последовательность, результирующий Shape сначала поворачивается, затем масштабируется и, наконец, перемещается.

at.translate(SIZE/2, SIZE/2);
at.scale(60, 60);
at.rotate(Math.PI/4);
return at.createTransformedShape(...);
person trashgod    schedule 01.10.2010
comment
Я подтвержу ваш ответ, так как ваше выражение Last-In , First Out вдохновило решение - person Pierre; 02.10.2010
comment
Это полезное понятие для рассуждений о результате; но, конечно же, здесь нет очереди, а есть только одно преобразование, которое включает в себя серию операций. - person trashgod; 02.10.2010

Вдохновленный ответом Trashgod, правильная последовательность была такой:

AffineTransform transforms[]=
{
AffineTransform.getScaleInstance(zoom, zoom),
AffineTransform.getTranslateInstance(viewRect.getX(),viewRect.getY()),
AffineTransform.getScaleInstance(ratioW, ratioH),
AffineTransform.getTranslateInstance(-bounds.getX(),-bounds.getY())
};



AffineTransform tr=new AffineTransform();
for(int i=0;i< transforms.length;++i)
 {
 tr.concatenate(transforms[i]);
 }
person Pierre    schedule 02.10.2010
comment
+1 Возможно, стоит добавить исходный код для сравнения до и после. - person trashgod; 02.10.2010