Skip to content

Instantly share code, notes, and snippets.

@vladholubiev
Created July 9, 2014 15:39
Show Gist options
  • Save vladholubiev/fe248aa3ad69ab5c574f to your computer and use it in GitHub Desktop.
Save vladholubiev/fe248aa3ad69ab5c574f to your computer and use it in GitHub Desktop.
package ua.samosfator.gmmtools;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.PrecisionModel;
import com.vividsolutions.jts.simplify.DouglasPeuckerSimplifier;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import java.util.*;
import java.util.List;
public class DrawPolygon {
private final JDialog frame = new JDialog();
private static ArrayList<Coordinate> coords = new ArrayList<>();
private static Geometry resultGeometry;
private List<Shape> shapes = new ArrayList<>();
private List<Point> pressedPoints = new ArrayList<>();
private List<Point> existVectors = new ArrayList<>();
private Shape currentShape = null;
private Color lineColor = Color.blue;
private Point vectorToAdd;
public void start() {
JComponent component = new JComponent() {
{
MouseAdapter mouseAdapter = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
currentShape = new Line2D.Double(e.getPoint(), e.getPoint());
shapes.add(currentShape);
coords.add(new Coordinate(e.getX(), e.getY()));
pressedPoints.add(new Point(e.getX(), e.getY()));
repaint();
}
public void mouseDragged(MouseEvent e) {
Line2D shape = (Line2D) currentShape;
shape.setLine(shape.getP1(), e.getPoint());
double rate = getMostParallel(new Point(getCurrVect(e)));
if (rate < 0.15 && rate >= 0.0) {
lineColor = Color.red;
} else lineColor = Color.blue;
repaint();
}
public void mouseReleased(MouseEvent e) {
coords.add(new Coordinate(e.getX(), e.getY()));
currentShape = null;
repaint();
existVectors.add(getCurrVect(e));
Robot bot;
try {
bot = new Robot();
bot.mousePress(InputEvent.BUTTON1_MASK);
} catch (AWTException ignored) { }
}
};
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(lineColor);
g2d.setStroke(new BasicStroke(7));
shapes.forEach(g2d::draw);
}
};
frame.setAlwaysOnTop(true);
frame.getContentPane().add(component);
frame.setMinimumSize(new Dimension(Screen.getWidth(), Screen.getHeight()));
frame.setUndecorated(true);
frame.setLocationRelativeTo(null);
frame.setBackground(new Color(1, 1, 1, (float) 0.1));
frame.setVisible(true);
frame.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
boolean isEscape = e.getKeyCode() == KeyEvent.VK_ESCAPE;
if (isEscape && coords.size() > 2) {
getNormalizedCoords();
frame.setVisible(false);
ActionPicker.show();
} else if (isEscape) {
frame.setVisible(false);
ActionPicker.show();
}
}
});
}
private void getNormalizedCoords() {
coords.add(new Coordinate(coords.get(0)));
Coordinate[] points = coords.toArray(new Coordinate[coords.size()]);
GeometryFactory g = new GeometryFactory(new PrecisionModel(), 1);
Geometry geo = g.createLinearRing(points);
DouglasPeuckerSimplifier simpl = new DouglasPeuckerSimplifier(geo);
simpl.setDistanceTolerance(15);
resultGeometry = simpl.getResultGeometry();
try {
frame.setVisible(false);
clickGeometry();
} catch (AWTException ignored) {
}
}
// Iterate coordinates and click on each one
private void clickGeometry() throws AWTException {
for (Coordinate c : resultGeometry.getCoordinates()) {
Robot bot = new Robot();
bot.mouseMove((int) c.x, (int) c.y);
bot.mousePress(InputEvent.BUTTON1_MASK);
bot.mouseRelease(InputEvent.BUTTON1_MASK);
bot.delay(500);
}
coords.clear();
}
private Point getCurrVect(MouseEvent e) {
try {
vectorToAdd = calcVectorCoord(
new Point(
(int) pressedPoints.get(pressedPoints.size() - 2).getX(),
(int) pressedPoints.get(pressedPoints.size() - 2).getY()
),
new Point(
e.getX(),
e.getY()
)
);
} catch (Exception ignored) { }
return vectorToAdd;
}
private Point calcVectorCoord(Point p1, Point p2) {
Point coord = new Point();
coord.x = (int) (p2.getX() - p1.getX());
coord.y = (int) (p2.getY() - p1.getY());
return coord;
}
private double getMostParallel(Point p) {
if (existVectors.size() > 2) {
double[] closest = new double[existVectors.size()];
// Find vector with coefficient most close to 1.
// This means last (drawing) vector is almost parallel to it
for (int i = 0; i < existVectors.size() - 1; i++) {
Point ex = existVectors.get(i);
double vector = 0;
try {
vector = ((ex.getX() / p.getX()) + (ex.getY() / p.getY())) / 2;
Arrays.sort(closest);
System.out.println(closest[1] + ", " + closest[2] + ", " + closest[3]);
} catch (Exception e) {
System.out.println(p);
}
closest[i] = Math.abs(1 - vector);
}
return closest[1];
} else return 12;
//12 (or any bigger coeff) means that vectors aren't parallel at all
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment