轮换不按我的意愿工作

时间:2010-08-12 21:27:22

标签: java image-processing rotation

我有以下类来旋转图像,当我给它旋转的程度,但它不能正常工作。问题在于,例如,如果我旋转90度,则旋转后,rotateCrossing()内的变量“currentRotationAngle”逐渐设置为90。发生这种情况是因为我总是通过偏移量(10)增加该变量。

下次我要旋转180度,因为变量已经是90,它只旋转另一个90(90 + 90 = 180)而不是整个180度。我试图通过在“stop()”方法中将“currentRotationAngle”设置为0来修复它,只要旋转结束,它就会让旋转返回到它的起始位置。

这就是我想要的,当我给它度数时,我希望它从最后一个旋转位置开始精确旋转到那个度数。请以下是课程。

public class CrossingPanel extends JPanel{

    private static final long serialVersionUID = 1L;

    // private data members
     private Image crossingImage;
     private int currentRotationAngle;
     private int imageWidth;
     private int imageHeight;
     private AffineTransform affineTransform;
     private boolean clockwise; 
     private static int ROTATE_ANGLE_OFFSET = 10;

     private boolean finishRotation = false;
     private int degreesToTurn;

     private static int LENGTH = 75;
    private static int RAIL_LENGTH = 130;
    private int ARROWLENGTH = 4;
    private static int TICKSIZE = 10;
    private GeneralPath path;
     private int xCoordinate;
     private int yCoordinate;

     private javax.swing.Timer timer;

     private void initialize(){
        //this.crossingImage = getImage("images/railCrossing.JPG");
         this.crossingImage = Toolkit.getDefaultToolkit().getImage("images/crossingsHorizontal.JPG");
        // MediaTracker mt = new MediaTracker(this);
        // mt.addImage(this.crossingImage, 1);
         this.path = new GeneralPath();
         this.imageWidth = this.getCrossingImage().getWidth(this);
         this.imageHeight = this.getCrossingImage().getHeight(this);
         this.affineTransform = new AffineTransform();
         this.setCurrentRotationAngle(0);
         this.setDegreesToTurn(0);
         timer = new javax.swing.Timer(20, new MoveListener());
           // timer.start();
     } 

    public CrossingPanel(int x, int y/*, BufferedImage img*/) {

        this.setxCoordinate(x);
        this.setyCoordinate(y);
        this.setPreferredSize(new Dimension(50, 50));
        this.setBackground(Color.red);
        TitledBorder border = BorderFactory.createTitledBorder("image");
        //this.setBorder(border);
        this.setLayout(new FlowLayout());
        this.initialize();

    }


    public GeneralPath getPath() {
        return path;
    }
    public void setPath(GeneralPath path) {
        this.path = path;
    }

    private void constructInterfaceComponents(){
    }

    private Shape createVerticalRail(){
        //System.out.print("dddd: " + this.LENGTH + "\n");
        this.getPath().moveTo(0, LENGTH);
        this.getPath().lineTo(RAIL_LENGTH,75);
        float cm = 72 / 2.54f;
        float lengthCentimeter = RAIL_LENGTH;

        for (float i = 260.0f, j = 340; i >= 0; i -= 15.0f, j += 20) {
              float tick = i * cm;
            //  path.moveTo(340, i);
            //  path.lineTo(360, i);
        }

        this.getPath().closePath();
        return this.getPath();
    }

    public void paintComponent(Graphics grp){ 

        Rectangle rect = this.getBounds();
        Graphics2D g2d = (Graphics2D)grp;

        //set the background color to black
        g2d.setColor(Color.BLACK);

       // g2d.draw(this.createVerticalRail());

        //set the translation to the mid of the component

        this.getAffineTransform().setToTranslation(this.getxCoordinate(), this.getyCoordinate());

          //rotate with the rotation point as the mid of the image
        this.getAffineTransform().rotate(Math.toRadians(this.getCurrentRotationAngle()), this.getCrossingImage().getWidth(this) /2, 
                                         this.getCrossingImage().getHeight(this)/2);

        //draw the image using the AffineTransform
        g2d.drawImage(this.getCrossingImage(), this.getAffineTransform(), this);
    }


    public void rotateCrossing(int degrees){
        // this condition is there to avoid division of zero
            // and also there is no need to rotate 0 degrees
            if(degrees == 0){
            this.stop();
            return;
        }
        currentRotationAngle += ROTATE_ANGLE_OFFSET;

            if (currentRotationAngle % degrees == 0) {
                timer.stop();
                this.finishRotation = true;
            }

         repaint(); 
    }



     public int getDegreesToTurn() {
        return degreesToTurn;
    }

    public void setDegreesToTurn(int degreesToTurn) {
        this.degreesToTurn = degreesToTurn;
    }



    private class MoveListener implements ActionListener {

            public void actionPerformed(ActionEvent e) {

                rotateCrossing(degreesToTurn);


        }

     }


     void start(int degreesToTurn) {
            if (timer != null) {
                timer.start();
            }
            this.setDegreesToTurn(degreesToTurn);
        }

     void stop() {
            timer.stop();
            this.setCurrentRotationAngle(0);

        }






    public Image getCrossingImage() {
        return crossingImage;
    }
    public void setCrossingImage(Image crossingImage) {
        this.crossingImage = crossingImage;
    }

    public int getCurrentRotationAngle() {
        return currentRotationAngle;
    }
    public void setCurrentRotationAngle(int currentRotationAngle) {
        this.currentRotationAngle = currentRotationAngle;
    }

    public int getImageWidth() {
        return imageWidth;
    }
    public void setImageWidth(int imageWidth) {
        this.imageWidth = imageWidth;
    }

    public int getImageHeight() {
        return imageHeight;
    }
    public void setImageHeight(int imageHeight) {
        this.imageHeight = imageHeight;
    }

    public AffineTransform getAffineTransform() {
        return affineTransform;
    }
    public void setAffineTransform(AffineTransform affineTransform) {
        this.affineTransform = affineTransform;
    }

    public boolean isClockwise() {
        return clockwise;
    }
    public void setClockwise(boolean clockwise) {
        this.clockwise = clockwise;
    }

    public int getxCoordinate() {
        return xCoordinate;
    }
    public void setxCoordinate(int xCoordinate) {
        this.xCoordinate = xCoordinate;
    }

    public int getyCoordinate() {
        return yCoordinate;
    }
    public void setyCoordinate(int yCoordinate) {
        this.yCoordinate = yCoordinate;
    }

    public javax.swing.Timer getTimer() {
        return timer;
    }
    public void setTimer(javax.swing.Timer timer) {
        this.timer = timer;
    }

    public  boolean isFinishRotation() {
        return finishRotation;
    }

    public void setFinishRotation(boolean finishRotation) {
        this.finishRotation = finishRotation;
    }



}

我希望有人帮我修复它。

谢谢大家。

1 个答案:

答案 0 :(得分:0)

这个方法对于度参数的目的是多么奇怪?  我想你用相同的度数值多次调用这个方法。在这种情况下,您应该使用度数的绝对值(270不是180)。

    public void rotateCrossing(int degrees){
    // this condition is there to avoid division of zero
        if(degrees == 0){
        this.stop();
        return;
    }
    currentRotationAngle += ROTATE_ANGLE_OFFSET;

        if (currentRotationAngle % degrees == 0) { // this line isn't correct I think
            timer.stop();
            this.finishRotation = true;
        }

     repaint(); 
    }

我建议使用以下代码:

private class MoveListener implements ActionListener {
    private int cyclesToGo;
    public MoveListener(){
        cyclesToGo = CrossingPanel.this.degreesToTurn / ROTATE_ANGLE_OFFSET; // how many time to call repaint
    }   

        public void actionPerformed(ActionEvent e) {
            if (cyclesToGo-- > 0) rotateCrossing();
            else {
                CrossingPanel.this.stop(); // call outer class methods
                 CrossingPanel.this.finishRotation = true; // call outer class methods
           }
       }

}
   // this method increments currentRotationAngle and calles repaint
   public void rotateCrossing(){
        currentRotationAngle += ROTATE_ANGLE_OFFSET;
        repaint(); 
   }