Skip to content

Instantly share code, notes, and snippets.

@hetelek
Created September 11, 2013 21:13
Show Gist options
  • Save hetelek/6529869 to your computer and use it in GitHub Desktop.
Save hetelek/6529869 to your computer and use it in GitHub Desktop.
An application which simulates a simple flip of a page in a book. Ported from C# - https://github.com/hetelek/BookFlip
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
// Ported from C# - https://github.com/hetelek/BookFlip
class MainForm
{
public static void main(String[] args)
{
JFrame frame = new JFrame("BookFlip");
frame.add(new BookFlip());
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
public class BookFlip extends JPanel
{
static final boolean POLYGON_MODE = true;
MouseHandler mouseHandler = new MouseHandler();
Point creaseOrigin, bottomRight, mousePoint;
int pageWidth, pageHeight;
boolean isBendingPaper;
public BookFlip()
{
super();
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
private void redrawPanel(Graphics2D g)
{
pageWidth = this.getWidth() / 2;
pageHeight = this.getHeight();
bottomRight = new Point(this.getWidth(), pageHeight);
creaseOrigin = new Point(pageWidth, pageHeight);
drawPages(g);
}
private void drawPages(Graphics2D g)
{
g.clearRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.BLUE);
g.fillRect(0, 0, pageWidth, pageHeight);
g.setColor(Color.RED);
g.fillRect(pageWidth, 0, pageWidth, pageHeight);
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
this.redrawPanel(g2d);
if (isBendingPaper)
{
double distance = getDistance(mousePoint, creaseOrigin);
if (distance > pageWidth)
mousePoint = getClosestPointOnCircle(mousePoint);
if (mousePoint.y >= pageHeight)
return;
Point midpoint = getMidpoint(mousePoint, bottomRight);
double m = -(double)(mousePoint.x - bottomRight.x) / (mousePoint.y - bottomRight.y);
double b = -((m * midpoint.x) - midpoint.y);
double x = (pageHeight - b) / m;
int yForEdgePoint = (int)(m * (pageWidth * 2) + b);
Point bottomPoint = new Point((int)x, pageHeight);
Point rightEdgePoint = new Point(pageWidth * 2, yForEdgePoint);
g2d.setColor(Color.GREEN);
if (POLYGON_MODE)
{
int[] xPoints = { rightEdgePoint.x, mousePoint.x, bottomPoint.x };
int[] yPoints = { rightEdgePoint.y, mousePoint.y, bottomPoint.y };
g2d.fillPolygon(xPoints, yPoints, xPoints.length);
xPoints[1] = bottomRight.x;
yPoints[1] = bottomRight.y;
g2d.setColor(Color.YELLOW);
g2d.fillPolygon(xPoints, yPoints, xPoints.length);
}
else
{
g2d.drawLine(rightEdgePoint.x, rightEdgePoint.y, bottomPoint.x, bottomPoint.y);
g2d.drawLine(mousePoint.x, mousePoint.y, bottomPoint.x, bottomPoint.y);
g2d.drawLine(mousePoint.x, mousePoint.y, rightEdgePoint.x, rightEdgePoint.y);
}
isBendingPaper = false;
}
}
private Point getMidpoint(Point p1, Point p2)
{
int x = (p1.x + p2.x) / 2;
int y = (p1.y + p2.y) / 2;
return new Point(x, y);
}
private double getDistance(Point p1, Point p2)
{
double x = Math.pow(p2.x - p1.x, 2);
double y = Math.pow(p2.y - p1.y, 2);
return Math.sqrt(x + y);
}
private Point getClosestPointOnCircle(Point p)
{
// no idea how this works, source below
// http://stackoverflow.com/questions/300871/best-way-to-find-a-point-on-a-circle-closest-to-a-given-point
double vX = p.x - creaseOrigin.x;
double vY = p.y - creaseOrigin.y;
double magV = Math.sqrt(vX * vX + vY * vY);
double aX = creaseOrigin.x + vX / magV * pageWidth;
double aY = creaseOrigin.y + vY / magV * pageWidth;
return new Point((int)aX, (int)aY);
}
private class MouseHandler extends MouseAdapter
{
@Override
public void mouseDragged(MouseEvent e)
{
mousePoint = new Point(e.getX(), e.getY());
isBendingPaper = true;
repaint();
}
@Override
public void mouseReleased(MouseEvent e)
{
mousePoint = new Point(e.getX(), e.getY());
isBendingPaper = false;
repaint();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment