package mypackage;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.event.*;
public class LocationTest extends JPanel implements ChangeListener
{
Ellipse2D.Double ball;
Line2D.Double line;
JSlider translate;
double lastTheta = 0;
public void stateChanged(ChangeEvent e)
{
JSlider slider = (JSlider)e.getSource();
String name = slider.getName();
int value = slider.getValue();
if(name.equals("rotation"))
tilt(Math.toRadians(value));
else if(name.equals("translate"))
moveBall(value);
repaint();
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint( RenderingHints.KEY_ ANTIALIASING,
RenderingHints.VALUE_ ANTIALIAS_ON);
if(ball == null)
initGeom();
g2.setPaint(Color.green. darker());
g2.draw(line);
g2.setPaint(Color.red);
g2.fill(ball);
}
private void initGeom()
{
int w = getWidth();
int h = getHeight();
int DIA = 30;
int padFromEnd = 5;
line = new Line2D.Double(w/4, h*15/16, w*3/4, h*15/16);
double x = line.x2 - padFromEnd - DIA;
double y = line.y2 - DIA;
ball = new Ellipse2D.Double(x, y, DIA, DIA);
// update translate slider values
int max = (int)line.getP1().distance( line.getP2());
translate.setMaximum(max);
translate.setValue(max- padFromEnd);
}
private void tilt(double theta)
{
// rotate line from left end
Point2D pivot = line.getP1();
double lineLength = pivot.distance(line.getP2());
Point2D.Double p2 = new Point2D.Double();
p2.x = pivot.getX() + lineLength*Math.cos(theta);
p2.y = pivot.getY() + lineLength*Math.sin(theta);
line.setLine(pivot, p2);
// find angle from pivot to ball center relative to line
// ie, ball center -> pivot -> line end
double cx = ball.getCenterX();
double cy = ball.getCenterY();
double pivotToCenter = pivot.distance(cx, cy);
// angle of ball to horizon
double dy = cy - pivot.getY();
double dx = cx - pivot.getX();
// relative angle phi = ball_to_horizon - last line_to_horizon
double phi = Math.atan2(dy, dx) - lastTheta;
// rotate ball from pivot
double x = pivot.getX() + pivotToCenter*Math.cos(theta+ phi);
double y = pivot.getY() + pivotToCenter*Math.sin(theta+ phi);
ball.setFrameFromCenter(x, y, x+ball.width/2, y+ball.height/2);
lastTheta = theta; // save theta for next time
}
private void moveBall(int distance)
{
Point2D pivot = line.getP1();
// ball touches line at distance from pivot
double contactX = pivot.getX() + distance*Math.cos(lastTheta);
double contactY = pivot.getY() + distance*Math.sin(lastTheta);
// find new center location of ball
// angle lambda = lastTheta - 90 degrees (anti-clockwise)
double lambda = lastTheta - Math.PI/2;
double x = contactX + (ball.width/2)*Math.cos( lambda);
double y = contactY + (ball.height/2)*Math.sin( lambda);
ball.setFrameFromCenter(x, y, x+ball.width/2, y+ball.height/2);
}
private JPanel getControls()
{
JSlider rotate = getSlider("rotation angle", "rotation", -90, 0, 0, 5, 15);
translate = getSlider("distance from end", "translate", 0, 100, 100,25, 50);
JPanel panel = new JPanel(new GridLayout(0,1));
panel.add(rotate);
panel.add(translate);
return panel;
}
private JSlider getSlider(String title, String name, int min, int max,
int value, int minorSpace, int majorSpace)
{
JSlider slider = new JSlider(JSlider.HORIZONTAL, min, max, value);
slider.setBorder( BorderFactory. createTitledBorder(title));
slider.setName(name);
slider.setPaintTicks(true);
slider.setMinorTickSpacing( minorSpace);
slider.setMajorTickSpacing( majorSpace);
slider.setPaintLabels(true);
slider.addChangeListener(this) ;
return slider;
}
public static void main(String[] args)
{
LocationTest test = new LocationTest();
JFrame f = new JFrame();
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(test);
f.getContentPane().add(test. getControls(), "Last");
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.event.*;
public class LocationTest extends JPanel implements ChangeListener
{
Ellipse2D.Double ball;
Line2D.Double line;
JSlider translate;
double lastTheta = 0;
public void stateChanged(ChangeEvent e)
{
JSlider slider = (JSlider)e.getSource();
String name = slider.getName();
int value = slider.getValue();
if(name.equals("rotation"))
tilt(Math.toRadians(value));
else if(name.equals("translate"))
moveBall(value);
repaint();
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(
RenderingHints.VALUE_
if(ball == null)
initGeom();
g2.setPaint(Color.green.
g2.draw(line);
g2.setPaint(Color.red);
g2.fill(ball);
}
private void initGeom()
{
int w = getWidth();
int h = getHeight();
int DIA = 30;
int padFromEnd = 5;
line = new Line2D.Double(w/4, h*15/16, w*3/4, h*15/16);
double x = line.x2 - padFromEnd - DIA;
double y = line.y2 - DIA;
ball = new Ellipse2D.Double(x, y, DIA, DIA);
// update translate slider values
int max = (int)line.getP1().distance(
translate.setMaximum(max);
translate.setValue(max-
}
private void tilt(double theta)
{
// rotate line from left end
Point2D pivot = line.getP1();
double lineLength = pivot.distance(line.getP2());
Point2D.Double p2 = new Point2D.Double();
p2.x = pivot.getX() + lineLength*Math.cos(theta);
p2.y = pivot.getY() + lineLength*Math.sin(theta);
line.setLine(pivot, p2);
// find angle from pivot to ball center relative to line
// ie, ball center -> pivot -> line end
double cx = ball.getCenterX();
double cy = ball.getCenterY();
double pivotToCenter = pivot.distance(cx, cy);
// angle of ball to horizon
double dy = cy - pivot.getY();
double dx = cx - pivot.getX();
// relative angle phi = ball_to_horizon - last line_to_horizon
double phi = Math.atan2(dy, dx) - lastTheta;
// rotate ball from pivot
double x = pivot.getX() + pivotToCenter*Math.cos(theta+
double y = pivot.getY() + pivotToCenter*Math.sin(theta+
ball.setFrameFromCenter(x, y, x+ball.width/2, y+ball.height/2);
lastTheta = theta; // save theta for next time
}
private void moveBall(int distance)
{
Point2D pivot = line.getP1();
// ball touches line at distance from pivot
double contactX = pivot.getX() + distance*Math.cos(lastTheta);
double contactY = pivot.getY() + distance*Math.sin(lastTheta);
// find new center location of ball
// angle lambda = lastTheta - 90 degrees (anti-clockwise)
double lambda = lastTheta - Math.PI/2;
double x = contactX + (ball.width/2)*Math.cos(
double y = contactY + (ball.height/2)*Math.sin(
ball.setFrameFromCenter(x, y, x+ball.width/2, y+ball.height/2);
}
private JPanel getControls()
{
JSlider rotate = getSlider("rotation angle", "rotation", -90, 0, 0, 5, 15);
translate = getSlider("distance from end", "translate", 0, 100, 100,25, 50);
JPanel panel = new JPanel(new GridLayout(0,1));
panel.add(rotate);
panel.add(translate);
return panel;
}
private JSlider getSlider(String title, String name, int min, int max,
int value, int minorSpace, int majorSpace)
{
JSlider slider = new JSlider(JSlider.HORIZONTAL, min, max, value);
slider.setBorder(
slider.setName(name);
slider.setPaintTicks(true);
slider.setMinorTickSpacing(
slider.setMajorTickSpacing(
slider.setPaintLabels(true);
slider.addChangeListener(this)
return slider;
}
public static void main(String[] args)
{
LocationTest test = new LocationTest();
JFrame f = new JFrame();
f.setDefaultCloseOperation(
f.getContentPane().add(test);
f.getContentPane().add(test.
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
No comments:
Post a Comment