如何到达指定位置后,旋转矩形? [英] How to rotate a rectangle after reaching specified position?

查看:185
本文介绍了如何到达指定位置后,旋转矩形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想旋转矩形时,例如y位置达到指定位置。我想表现一个矩形作为一个路口一辆汽车 - 只是把如对。我preFER只需旋转并继续。

一个$草案C $ C看起来像:

 的Graphics2D G2D =(Graphics2D的)g.create();
g2d.setPaint(新的色彩(150,150,0));// 1。当矩形的y维度达到500只左/右旋转
如果(Y == 500){
    _rotate = TRUE;
    g2d.rotate(Math.toRadians(90)。);
}
如果(_rotate){//如果旋转,继续X尺寸的方法
    + X;
    g2d.fillRect(X,Y​​,20,40);
}其他{//别的向北走
    --y;
    g2d.fillRect(X,Y​​,20,40);
}


解决方案

有很多的信息,这是从你的问题丢失。

为了能够旋转的形状,你需要知道一些事情,你需要知道它的当前位置和它的下一个目标位置,那么你可以简单地计算这两个点之间的夹角。

问题就变成了,你如何计算这些位置。有很多人可能实现这一目标的方式,下面是一个简单的路径跟踪的过程。

首先,我们生成这就需要我们遵循的路径,我们使用图形 API沿着路径计算点。我们用一个简单的基于时间的动画和采摘点(而通过点的循环,我们通过计算时间量的动画已经打通过,我们希望它采取的时间量除以计算沿路径的进步),它最好符合我们目前的进展。

我们使用的AffineTransform 旋转播放器形状和所产生的图形转换到需要的位置。缓解

的FollowMe

 进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.Rectangle中;
进口java.awt.Shape中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口java.awt.event.KeyEvent中;
进口java.awt.geom.AffineTransform中;
进口java.awt.geom.Path2D;
进口java.awt.geom.PathIterator中;
进口java.awt.geom.Point2D中;
进口的java.util.ArrayList;
进口的java.util.List;
进口javax.swing.AbstractAction中;
进口javax.swing.ActionMap中;
进口javax.swing.InputMap中;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.KeyStroke;
进口javax.swing.Timer中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;公共类PathFollow {    公共静态无效的主要(字串[] args){
        新PathFollow();
    }    公共PathFollow(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                    ex.printStackTrace();
                }                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(新TestPane());
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }
        });
    }    公共类TestPane继承JPanel {        私人形状pathShape;
        私人列表<&的Point2D GT;点;
        私家车形状;        私人双角;
        私人的Point2D POS;
        私人诠释指数;        受保护的静态最后双play_time增加= 5000; //5秒...        私人长期的startTime;        公共TestPane(){            Path2D路径=新Path2D.Double();
            path.moveTo(0,200);
            path.curveTo(100,200,0,100,100,100);
            path.curveTo(200,100,0,0,200,0);            pathShape =路径;            汽车=新的Rectangle(0,0,10,10);            点=新的ArrayList<>(25);
            PI的PathIterator = pathShape.getPathIterator(NULL,0.01)。
            而(!pi.isDone()){
                双[] = COORDS新的双[6];
                开关(pi.currentSegment(COORDS)){
                    案例PathIterator.SEG_MOVETO:
                    案例PathIterator.SEG_LINETO:
                        points.add(新Point2D.Double(COORDS [0],COORDS [1]));
                        打破;
                }
                pi.next();
            }//的System.out.println(points.size());
// POS = points.get(0);
//索引= 1;
            定时器定时器=新定时器(40,新的ActionListener(){
                @覆盖
                公共无效的actionPerformed(ActionEvent的五){                    如果(startTime时== NULL){
                        STARTTIME = System.currentTimeMillis的();
                    }
                    长playTime内容= System.currentTimeMillis的() - startTime时;
                    双进度= playTime内容/ play_time增加;
                    如果(进度> = 1.0){
                        进度= 1D;
                        ((定时器)e.getSource())停止();
                    }                    INT指数= Math.min(Math.max(0,(int)的(points.size()*进展)),points.size() - 1);                    POS = points.get(指数);
                    如果(指数< points.size() - 1){
                        角= angleTo(POS,points.get(索引+ 1));
                    }
                    重绘();
                }
            });
            timer.start();
        }        @覆盖
        公共尺寸的get preferredSize(){
            返回新尺寸(200,200);
        }        @覆盖
        保护无效paintComponent(图形G){
            super.paintComponent方法(G);
            Graphics2D的G2D =(Graphics2D的)g.create();
            g2d.draw(pathShape);            在的AffineTransform =新AffineTransform();            如果(POS!= NULL){                矩形范围= car.getBounds();
                at.rotate(角度,(bounds.width / 2),(bounds.width / 2));                Path2D球员=新Path2D.Double(汽车,AT);                g2d.translate(pos.getX() - (bounds.width / 2),pos.getY() - (bounds.height / 2));
                g2d.draw(播放器);            }            g2d.dispose();
        }        //弧度...
        保护双angleTo(从的Point2D,Point2D到){
            双角= Math.atan2(to.getY() - from.getY(),to.getX() - from.getX());
            返回角;
        }    }}

I would like to rotate a rectangle when e.g. y position achieve specified position. I would like to behave a rectangle as a car on a junction - just turn e.g. right. I prefer just rotate and continue.

A draft code looks like that:

Graphics2D g2d = (Graphics2D) g.create();
g2d.setPaint(new Color(150, 150, 0));

//1. when rectangle achieve 500 on y dimension just rotate left/right
if(y==500) {
    _rotate = true;
    g2d.rotate(Math.toRadians(90.));
}
if(_rotate) { //if rotate, continue way on x dimension
    ++x ;
    g2d.fillRect(x, y, 20, 40);
} else { //else go to the north
    --y;
    g2d.fillRect(x, y, 20, 40);
}

解决方案

There is a lot of information which is missing from your question.

In order to be able to rotate a shape, you need to know a few things, you need to know it's current position and it's next target position, then you can simply calculate the angle between these two points.

The question then becomes, how do you calculate these positions. There are plenty of ways you might achieve this, the following is a simple path following process.

First, we generate a path which we need to follow, we use the Shape API to calculate the points along the path. We use a simple time based animation (rather the looping through the points, we calculate the progress along the path by calculating amount of time the animation has been playing divided by the amount of time we want it to take) and picking the point which best matches our current progress.

We use a AffineTransform to rotate the player shape and the translate the resulting Shape to the required position. Ease

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class PathFollow {

    public static void main(String[] args) {
        new PathFollow();
    }

    public PathFollow() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Shape pathShape;
        private List<Point2D> points;
        private Shape car;

        private double angle;
        private Point2D pos;
        private int index;

        protected static final double PLAY_TIME = 5000; // 5 seconds...

        private Long startTime;

        public TestPane() {

            Path2D path = new Path2D.Double();
            path.moveTo(0, 200);
            path.curveTo(100, 200, 0, 100, 100, 100);
            path.curveTo(200, 100, 0, 0, 200, 0);

            pathShape = path;

            car = new Rectangle(0, 0, 10, 10);

            points = new ArrayList<>(25);
            PathIterator pi = pathShape.getPathIterator(null, 0.01);
            while (!pi.isDone()) {
                double[] coords = new double[6];
                switch (pi.currentSegment(coords)) {
                    case PathIterator.SEG_MOVETO:
                    case PathIterator.SEG_LINETO:
                        points.add(new Point2D.Double(coords[0], coords[1]));
                        break;
                }
                pi.next();
            }

//          System.out.println(points.size());
//          pos = points.get(0);
//          index = 1;
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    if (startTime == null) {
                        startTime = System.currentTimeMillis();
                    }
                    long playTime = System.currentTimeMillis() - startTime;
                    double progress = playTime / PLAY_TIME;
                    if (progress >= 1.0) {
                        progress = 1d;
                        ((Timer) e.getSource()).stop();
                    }

                    int index = Math.min(Math.max(0, (int) (points.size() * progress)), points.size() - 1);

                    pos = points.get(index);
                    if (index < points.size() - 1) {
                        angle = angleTo(pos, points.get(index + 1));
                    }
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.draw(pathShape);

            AffineTransform at = new AffineTransform();

            if (pos != null) {

                Rectangle bounds = car.getBounds();
                at.rotate(angle, (bounds.width / 2), (bounds.width / 2));

                Path2D player = new Path2D.Double(car, at);

                g2d.translate(pos.getX() - (bounds.width / 2), pos.getY() - (bounds.height / 2));
                g2d.draw(player);

            }

            g2d.dispose();
        }

        // In radians...
        protected double angleTo(Point2D from, Point2D to) {
            double angle = Math.atan2(to.getY() - from.getY(), to.getX() - from.getX());
            return angle;
        }

    }

}

这篇关于如何到达指定位置后,旋转矩形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆