/** * ORIPA - Origami Pattern Editor * Copyright (C) 2005-2009 Jun Mitani http://mitani.cs.tsukuba.ac.jp/ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package oripa; import java.awt.*; import java.awt.event.*; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.vecmath.Vector2d; import oripa.geom.*; public class RenderScreenForCheck extends JPanel implements MouseListener, MouseMotionListener, MouseWheelListener, ActionListener, ComponentListener { private boolean bDrawFaceID = false; private Image bufferImage; private Graphics2D bufferg; private Point2D preMousePoint; // Screen coordinates private Point2D currentMouseDraggingPoint = null; private Point2D.Double currentMousePointLogic = new Point2D.Double(); // Logical coordinates private double scale; private double transX; private double transY; // Temporary information when editing private OriLine prePickLine = null; private Vector2d prePickV = null; private Vector2d preprePickV = null; private Vector2d prepreprePickV = null; private Vector2d pickCandidateV = null; private OriLine pickCandidateL = null; private ArrayList<Vector2d> tmpOutline = new ArrayList<>(); // Contour line in the edit private boolean dispGrid = true; // Affine transformation information private Dimension preSize; private AffineTransform affineTransform = new AffineTransform(); private ArrayList<Vector2d> crossPoints = new ArrayList<>(); private JPopupMenu popup = new JPopupMenu(); private JMenuItem popupItem_DivideFace = new JMenuItem("Face division"); private JMenuItem popupItem_FlipFace = new JMenuItem("Face Inversion"); RenderScreenForCheck() { addMouseListener(this); addMouseMotionListener(this); addMouseWheelListener(this); addComponentListener(this); scale = 1.5; setBackground(Color.white); popupItem_DivideFace.addActionListener(this); popup.add(popupItem_DivideFace); popupItem_FlipFace.addActionListener(this); popup.add(popupItem_FlipFace); preSize = getSize(); } public void drawModel(Graphics2D g2d) { for (OriFace face : ORIPA.doc.faces) { g2d.setColor(new Color(255, 210, 210)); g2d.fill(face.preOutline); } g2d.setColor(Color.RED); for (OriVertex v : ORIPA.doc.vertices) { if (v.hasProblem) { g2d.fill(new Rectangle2D.Double(v.preP.x - 8.0 / scale, v.preP.y - 8.0 / scale, 16.0 / scale, 16.0 / scale)); } } if (bDrawFaceID) { g2d.setColor(Color.BLACK); for (OriFace face : ORIPA.doc.faces) { g2d.drawString("" + face.tmpInt, (int) face.getCenter().x, (int) face.getCenter().y); } } if (Config.FOR_STUDY) { g2d.setColor(new Color(255, 210, 220)); for (OriFace face : ORIPA.doc.faces) { if (face.tmpInt2 == 0) { g2d.setColor(Color.RED); g2d.fill(face.preOutline); } else { g2d.setColor(face.color); } if (face.hasProblem) { g2d.setColor(Color.RED); } else { if (face.faceFront) { g2d.setColor(new Color(255, 200, 200)); } else { g2d.setColor(new Color(200, 200, 255)); } } g2d.fill(face.preOutline); } g2d.setColor(Color.BLACK); for (OriFace face : ORIPA.doc.faces) { g2d.drawString("" + face.z_order, (int) face.getCenter().x, (int) face.getCenter().y); } g2d.setColor(Color.RED); for (OriVertex v : ORIPA.doc.vertices) { if (v.hasProblem) { g2d.fill(new Rectangle2D.Double(v.p.x - 8.0 / scale, v.p.y - 8.0 / scale, 16.0 / scale, 16.0 / scale)); } } } } // To update the current AffineTransform private void updateAffineTransform() { affineTransform.setToIdentity(); affineTransform.translate(getWidth() * 0.5, getHeight() * 0.5); affineTransform.scale(scale, scale); affineTransform.translate(transX, transY); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); if (bufferImage == null) { bufferImage = createImage(getWidth(), getHeight()); bufferg = (Graphics2D) bufferImage.getGraphics(); updateAffineTransform(); preSize = getSize(); } bufferg.setTransform(new AffineTransform()); bufferg.setColor(Color.WHITE); bufferg.fillRect(0, 0, getWidth(), getHeight()); bufferg.setTransform(affineTransform); Graphics2D g2d = bufferg; g2d.setStroke(Config.STROKE_VALLEY); g2d.setColor(Color.black); for (OriLine line : ORIPA.doc.lines) { switch (line.type) { case OriLine.TYPE_NONE: if (!Globals.dispAuxLines) { continue; } g2d.setColor(Config.LINE_COLOR_AUX); g2d.setStroke(Config.STROKE_CUT); break; case OriLine.TYPE_CUT: g2d.setColor(Color.BLACK); g2d.setStroke(Config.STROKE_CUT); break; case OriLine.TYPE_RIDGE: if (!Globals.dispMVLines) { continue; } g2d.setColor(Config.LINE_COLOR_RIDGE); g2d.setStroke(Config.STROKE_RIDGE); break; case OriLine.TYPE_VALLEY: if (!Globals.dispMVLines) { continue; } g2d.setColor(Config.LINE_COLOR_VALLEY); g2d.setStroke(Config.STROKE_VALLEY); break; } if ((Globals.editMode == Constants.EditMode.INPUT_LINE && Globals.lineInputMode == Constants.LineInputMode.MIRROR && line.selected) || (Globals.editMode == Constants.EditMode.PICK_LINE && line.selected)) { g2d.setColor(Color.RED); g2d.setStroke(Config.STROKE_PICKED); } if (line == prePickLine) { g2d.setColor(Color.RED); g2d.setStroke(Config.STROKE_PICKED); } else if (line == pickCandidateL) { g2d.setColor(Config.LINE_COLOR_CANDIDATE); g2d.setStroke(Config.STROKE_PICKED); } g2d.draw(new Line2D.Double(line.p0.x, line.p0.y, line.p1.x, line.p1.y)); } // Drawing of the vertices for (OriVertex v : ORIPA.doc.vertices) { double vertexDrawSize = 2.0; g2d.setColor(Color.BLACK); if (v.hasProblem) { vertexDrawSize = 5.0; g2d.setColor(Color.RED); } g2d.fill(new Rectangle2D.Double(v.preP.x - vertexDrawSize / scale, v.preP.y - vertexDrawSize / scale, vertexDrawSize * 2 / scale, vertexDrawSize * 2 / scale)); } for (Vector2d v : crossPoints) { g2d.setColor(Color.RED); g2d.fill(new Rectangle2D.Double(v.x - 5.0 / scale, v.y - 5.0 / scale, 10.0 / scale, 10.0 / scale)); } // Line connecting the pair of unsetled faces if (Config.FOR_STUDY) { if (ORIPA.doc.overlapRelation != null) { g2d.setStroke(Config.STROKE_RIDGE); g2d.setColor(Color.MAGENTA); int size = ORIPA.doc.faces.size(); for (int i = 0; i < size; i++) { for (int j = i + 1; j < size; j++) { if (ORIPA.doc.overlapRelation[i][j] == Doc.UNDEFINED) { Vector2d v0 = ORIPA.doc.faces.get(i).getCenter(); Vector2d v1 = ORIPA.doc.faces.get(j).getCenter(); g2d.draw(new Line2D.Double(v0.x, v0.y, v1.x, v1.y)); } } } } } drawModel(g2d); g.drawImage(bufferImage, 0, 0, this); } public void setDispGrid(boolean dispGrid) { this.dispGrid = dispGrid; resetPickElements(); repaint(); } // 0: OriLine // 1: The nearest point Vector private boolean pickPointOnLine(Point2D.Double p, Object[] line_vertex) { double minDistance = Double.MAX_VALUE; OriLine bestLine = null; Vector2d nearestPoint = new Vector2d(); Vector2d tmpNearestPoint = new Vector2d(); for (OriLine line : ORIPA.doc.lines) { double dist = GeomUtil.DistancePointToSegment(new Vector2d(p.x, p.y), line.p0, line.p1, tmpNearestPoint); if (dist < minDistance) { minDistance = dist; bestLine = line; nearestPoint.set(tmpNearestPoint); } } if (minDistance / scale < 5) { line_vertex[0] = bestLine; line_vertex[1] = nearestPoint; return true; } else { return false; } } private Vector2d pickVertex(Point2D.Double p) { double minDistance = Double.MAX_VALUE; Vector2d minPosition = new Vector2d(); for (OriLine line : ORIPA.doc.lines) { double dist0 = p.distance(line.p0.x, line.p0.y); if (dist0 < minDistance) { minDistance = dist0; minPosition.set(line.p0); } double dist1 = p.distance(line.p1.x, line.p1.y); if (dist1 < minDistance) { minDistance = dist1; minPosition.set(line.p1); } } if (dispGrid) { double step = ORIPA.doc.size / Globals.gridDivNum; for (int ix = 0; ix < Globals.gridDivNum + 1; ix++) { for (int iy = 0; iy < Globals.gridDivNum + 1; iy++) { double x = -ORIPA.doc.size / 2 + step * ix; double y = -ORIPA.doc.size / 2 + step * iy; double dist = p.distance(x, y); if (dist < minDistance) { minDistance = dist; minPosition.set(x, y); } } } } if (minDistance < 10.0 / scale) { return minPosition; } else { return null; } } public void modeChanged() { resetPickElements(); repaint(); } public void resetPickElements() { prePickV = null; prePickLine = null; pickCandidateV = null; preprePickV = null; prepreprePickV = null; crossPoints.clear(); tmpOutline.clear(); } private OriLine pickLine(Point2D.Double p) { double minDistance = Double.MAX_VALUE; OriLine bestLine = null; for (OriLine line : ORIPA.doc.lines) { if (Globals.editMode == Constants.EditMode.DELETE_LINE) { } double dist = GeomUtil.DistancePointToSegment(new Vector2d(p.x, p.y), line.p0, line.p1); if (dist < minDistance) { minDistance = dist; bestLine = line; } } if (minDistance / scale < 10) { return bestLine; } else { return null; } } @Override public void mouseClicked(MouseEvent e) { if (javax.swing.SwingUtilities.isRightMouseButton(e)) { if (prepreprePickV != null) { prepreprePickV = null; repaint(); } else if (preprePickV != null) { preprePickV = null; repaint(); } else if (prePickV != null) { prePickV = null; repaint(); } else if (!tmpOutline.isEmpty()) { tmpOutline.remove(tmpOutline.size() - 1); repaint(); } if (Globals.editMode == Constants.EditMode.INPUT_LINE && Globals.lineInputMode == Constants.LineInputMode.COPY_AND_PASTE) { Globals.lineInputMode = Constants.LineInputMode.DIRECT_V; ORIPA.mainFrame.uiPanel.modeChanged(); ORIPA.doc.tmpSelectedLines.clear(); repaint(); } return; } if (Globals.editMode == Constants.EditMode.NONE) { return; } // Gets the logical coordinates of the click Point2D.Double clickPoint = new Point2D.Double(); try { affineTransform.inverseTransform(e.getPoint(), clickPoint); } catch (Exception ex) { return; } if (Globals.editMode == Constants.EditMode.CHANGE_LINE_TYPE) { OriLine l = pickLine(clickPoint); if (l != null) { ORIPA.doc.pushUndoInfo(); if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) { // When you press the Ctrl: outline l.type = OriLine.TYPE_CUT; } else { l.changeToNextType(); } } repaint(); return; } else if (Globals.editMode == Constants.EditMode.DELETE_LINE) { OriLine l = pickLine(clickPoint); if (l != null) { ORIPA.doc.pushUndoInfo(); ORIPA.doc.removeLine(l); } repaint(); return; } else if (Globals.editMode == Constants.EditMode.PICK_LINE) { OriLine l = pickLine(clickPoint); if (l != null) { // skip if ocult if (!Globals.dispMVLines && (l.type == OriLine.TYPE_RIDGE || l.type == OriLine.TYPE_VALLEY)) { return; } if (!Globals.dispAuxLines && l.type == OriLine.TYPE_NONE) { return; } l.selected = !l.selected; } repaint(); return; } else if (Globals.editMode == Constants.EditMode.ADD_VERTEX) { Object[] line_vertex = new Object[2]; if (pickPointOnLine(currentMousePointLogic, line_vertex)) { ORIPA.doc.pushUndoInfo(); if (!ORIPA.doc.addVertexOnLine((OriLine) line_vertex[0], (Vector2d) line_vertex[1])) { ORIPA.doc.popUndoInfo(); } this.pickCandidateV = null; repaint(); } return; } else if (Globals.editMode == Constants.EditMode.DELETE_VERTEX) { Vector2d v = pickVertex(clickPoint); if (v != null) { ORIPA.doc.pushUndoInfo(); ORIPA.doc.removeVertex(v); repaint(); } return; } else if (Globals.editMode == Constants.EditMode.EDIT_OUTLINE) { Vector2d v = pickVertex(currentMousePointLogic); // Add the outline being edited if (v != null) { // Closes if match existing point boolean bClose = false; for (Vector2d tv : tmpOutline) { if (GeomUtil.Distance(v, tv) < 1) { bClose = true; break; } } if (bClose) { if (tmpOutline.size() > 2) { closeTmpOutline(); } } else { tmpOutline.add(v); } repaint(); } return; } else if (Globals.editMode == Constants.EditMode.INPUT_LINE) { if (Globals.lineInputMode == Constants.LineInputMode.DIRECT_V) { Vector2d v = pickVertex(clickPoint); if (v == null) { if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) { OriLine l = pickLine(clickPoint); if (l != null) { v = new Vector2d(); Vector2d cp = new Vector2d(clickPoint.x, clickPoint.y); GeomUtil.DistancePointToSegment(cp, l.p0, l.p1, v); } } } if (v != null) { if (prePickV == null) { prePickV = v; } else { OriLine line = new OriLine(prePickV, v, Globals.inputLineType); ORIPA.doc.pushUndoInfo(); ORIPA.doc.addLine(line); prePickV = null; } } } else if (Globals.lineInputMode == Constants.LineInputMode.PBISECTOR) { Vector2d v = pickVertex(clickPoint); if (v != null) { if (prePickV == null) { prePickV = v; } else { ORIPA.doc.pushUndoInfo(); ORIPA.doc.addPBisector(prePickV, v); prePickV = null; } } } else if (Globals.lineInputMode == Constants.LineInputMode.COPY_AND_PASTE) { Vector2d v = pickVertex(clickPoint); if (v != null) { if (!ORIPA.doc.tmpSelectedLines.isEmpty()) { ORIPA.doc.pushUndoInfo(); double ox = ORIPA.doc.tmpSelectedLines.get(0).p0.x; double oy = ORIPA.doc.tmpSelectedLines.get(0).p0.y; for (OriLine l : ORIPA.doc.tmpSelectedLines) { double mx = v.x; double my = v.y; double sx = mx + l.p0.x - ox; double sy = my + l.p0.y - oy; double ex = mx + l.p1.x - ox; double ey = my + l.p1.y - oy; OriLine line = new OriLine(sx, sy, ex, ey, l.type); ORIPA.doc.addLine(line); } } } } else if (Globals.lineInputMode == Constants.LineInputMode.ON_V) { Vector2d v = pickVertex(clickPoint); if (v == null) { if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) { OriLine l = pickLine(clickPoint); if (l != null) { v = new Vector2d(); Vector2d cp = new Vector2d(clickPoint.x, clickPoint.y); GeomUtil.DistancePointToSegment(cp, l.p0, l.p1, v); } } } if (v != null) { if (prePickV == null) { prePickV = v; } else { Vector2d dir = new Vector2d(v.x - prePickV.x, v.y - prePickV.y); dir.normalize(); dir.scale(Constants.DEFAULT_PAPER_SIZE * 8); OriLine line = new OriLine(prePickV.x - dir.x, prePickV.y - dir.y, prePickV.x + dir.x, prePickV.y + dir.y, Globals.inputLineType); if (GeomUtil.clipLine(line, ORIPA.doc.size / 2)) { ORIPA.doc.pushUndoInfo(); ORIPA.doc.addLine(line); } prePickV = null; } } } else if (Globals.lineInputMode == Constants.LineInputMode.SYMMETRIC_LINE) { Vector2d v = pickVertex(clickPoint); if (v != null) { if (preprePickV == null) { preprePickV = v; } else if (prePickV == null) { prePickV = v; } else { ORIPA.doc.pushUndoInfo(); if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) { ORIPA.doc.addSymmetricLineAutoWalk(preprePickV, prePickV, v, 0, preprePickV); } else { ORIPA.doc.addSymmetricLine(preprePickV, prePickV, v); } prePickV = null; preprePickV = null; } } } else if (Globals.lineInputMode == Constants.LineInputMode.TRIANGLE_SPLIT) { Vector2d v = pickVertex(clickPoint); if (v != null) { if (preprePickV == null) { preprePickV = v; } else if (prePickV == null) { prePickV = v; } else { ORIPA.doc.pushUndoInfo(); ORIPA.doc.addTriangleDivideLines(v, prePickV, preprePickV); prePickV = null; preprePickV = null; } } } else if (Globals.lineInputMode == Constants.LineInputMode.BISECTOR) { if (prepreprePickV == null) { prepreprePickV = pickVertex(clickPoint); if (prepreprePickV != null) { pickCandidateV = null; } } else if (preprePickV == null) { preprePickV = pickVertex(clickPoint); } else if (prePickV == null) { prePickV = pickVertex(clickPoint); } else { OriLine l = pickLine(clickPoint); if (l != null) { ORIPA.doc.pushUndoInfo(); ORIPA.doc.addBisectorLine(prepreprePickV, preprePickV, prePickV, l); prePickV = null; preprePickV = null; prepreprePickV = null; } } } else if (Globals.lineInputMode == Constants.LineInputMode.VERTICAL_LINE) { if (prePickV == null) { prePickV = pickVertex(clickPoint); if (prePickV != null) { pickCandidateV = null; } pickCandidateV = null; } else { OriLine l = pickLine(clickPoint); if (l != null) { OriLine vl = GeomUtil.getVerticalLine(prePickV, l, Globals.inputLineType); ORIPA.doc.pushUndoInfo(); ORIPA.doc.addLine(vl); prePickV = null; } } } else if (Globals.lineInputMode == Constants.LineInputMode.MIRROR) { OriLine l = pickLine(clickPoint); if (l != null) { if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) { ORIPA.doc.mirrorCopyBy(l); ORIPA.doc.resetSelectedOriLines(); ORIPA.doc.pushUndoInfo(); } else { l.selected = !l.selected; } } repaint(); return; } else if (Globals.lineInputMode == Constants.LineInputMode.BY_VALUE) { if (Globals.subLineInputMode == Constants.SubLineInputMode.NONE) { Vector2d v = pickVertex(clickPoint); if (v != null) { double length; double angle; try { length = Double.valueOf(ORIPA.mainFrame.uiPanel.textFieldLength.getText()); angle = Double.valueOf(ORIPA.mainFrame.uiPanel.textFieldAngle.getText()); if (length > 0) { OriLine vl = GeomUtil.getLineByValue(v, length, -angle, Globals.inputLineType); ORIPA.doc.pushUndoInfo(); ORIPA.doc.addLine(vl); } } catch (Exception ex) { } } } else if (Globals.subLineInputMode == Constants.SubLineInputMode.PICK_LENGTH) { Vector2d v = pickVertex(clickPoint); if (v != null) { if (prePickV == null) { prePickV = v; } else { double length = GeomUtil.Distance(prePickV, v); ORIPA.mainFrame.uiPanel.textFieldLength.setValue(new Double(length)); Globals.subLineInputMode = Constants.SubLineInputMode.NONE; ORIPA.mainFrame.uiPanel.modeChanged(); } } } else if (Globals.subLineInputMode == Constants.SubLineInputMode.PICK_ANGLE) { Vector2d v = pickVertex(clickPoint); if (v != null) { if (preprePickV == null) { preprePickV = v; } else if (prePickV == null) { prePickV = v; } else { Vector2d dir1 = new Vector2d(v); Vector2d dir2 = new Vector2d(preprePickV); dir1.sub(prePickV); dir2.sub(prePickV); double deg_angle = Math.toDegrees(dir1.angle(dir2)); ORIPA.mainFrame.uiPanel.textFieldAngle.setValue(new Double(deg_angle)); Globals.subLineInputMode = Constants.SubLineInputMode.NONE; ORIPA.mainFrame.uiPanel.modeChanged(); } } } } } repaint(); } private Vector2d isOnTmpOutlineLoop(Vector2d v) { for (int i = 0; i < tmpOutline.size(); i++) { Vector2d p0 = tmpOutline.get(i); Vector2d p1 = tmpOutline.get((i + 1) % tmpOutline.size()); if (GeomUtil.DistancePointToLine(v, new Line(p0, new Vector2d(p1.x - p0.x, p1.y - p0.y))) < ORIPA.doc.size * 0.001) { return p0; } } return null; } private boolean isOutsideOfTmpOutlineLoop(Vector2d v) { Vector2d p0 = tmpOutline.get(0); Vector2d p1 = tmpOutline.get(1); boolean CCWFlg = GeomUtil.CCWcheck(p0, p1, v); for (int i = 1; i < tmpOutline.size(); i++) { p0 = tmpOutline.get(i); p1 = tmpOutline.get((i + 1) % tmpOutline.size()); if (CCWFlg != GeomUtil.CCWcheck(p0, p1, v)) { return true; } } return false; } private void closeTmpOutline() { ORIPA.doc.pushUndoInfo(); // Delete the current outline ArrayList<OriLine> outlines = new ArrayList<>(); for (OriLine line : ORIPA.doc.lines) { if (line.type == OriLine.TYPE_CUT) { outlines.add(line); } } for (OriLine line : outlines) { ORIPA.doc.lines.remove(line); } // Update the contour line int outlineVnum = tmpOutline.size(); for (int i = 0; i < outlineVnum; i++) { OriLine line = new OriLine(tmpOutline.get(i), tmpOutline.get((i + 1) % outlineVnum), OriLine.TYPE_CUT); ORIPA.doc.addLine(line); } // To delete a segment of the outer contour while (true) { boolean bDeleteLine = false; for (OriLine line : ORIPA.doc.lines) { if (line.type == OriLine.TYPE_CUT) { continue; } Vector2d OnPoint0 = isOnTmpOutlineLoop(line.p0); Vector2d OnPoint1 = isOnTmpOutlineLoop(line.p1); // Delete(if you're overlap with contour lines if (OnPoint0 != null && OnPoint0 == OnPoint1) { ORIPA.doc.removeLine(line); bDeleteLine = true; break; } // Also delete if one point is out if ((OnPoint0 == null && isOutsideOfTmpOutlineLoop(line.p0)) || (OnPoint1 == null && isOutsideOfTmpOutlineLoop(line.p1))) { ORIPA.doc.removeLine(line); bDeleteLine = true; break; } } if (!bDeleteLine) { break; } } tmpOutline.clear(); Globals.editMode = Globals.preEditMode; ORIPA.mainFrame.uiPanel.modeChanged(); } @Override public void mousePressed(MouseEvent e) { preMousePoint = e.getPoint(); } @Override public void mouseReleased(MouseEvent arg0) { // Retangular selection if (Globals.editMode == Constants.EditMode.PICK_LINE) { Point2D.Double sp = new Point2D.Double(); Point2D.Double ep = new Point2D.Double(); try { affineTransform.inverseTransform(preMousePoint, sp); affineTransform.inverseTransform(currentMouseDraggingPoint, ep); RectangleClipper clipper = new RectangleClipper(Math.min(sp.x, ep.x), Math.min(sp.y, ep.y), Math.max(sp.x, ep.x), Math.max(sp.y, ep.y)); for (OriLine l : ORIPA.doc.lines) { if (l.type == OriLine.TYPE_CUT) { continue; } // skip if ocult if (!Globals.dispMVLines && (l.type == OriLine.TYPE_RIDGE || l.type == OriLine.TYPE_VALLEY)) { continue; } if (!Globals.dispAuxLines && l.type == OriLine.TYPE_NONE) { continue; } if (clipper.clipTest(l)) { l.selected = true; } } } catch (Exception ex) { } } currentMouseDraggingPoint = null; repaint(); } @Override public void mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @Override public void mouseDragged(MouseEvent e) { if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 && // zoom (e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) { double moved = e.getX() - preMousePoint.getX() + e.getY() - preMousePoint.getY(); scale += moved / 150.0; if (scale < 0.01) { scale = 0.01; } preMousePoint = e.getPoint(); updateAffineTransform(); repaint(); } else if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0) { transX += (double) (e.getX() - preMousePoint.getX()) / scale; transY += (double) (e.getY() - preMousePoint.getY()) / scale; preMousePoint = e.getPoint(); updateAffineTransform(); repaint(); } else if (Globals.editMode == Constants.EditMode.PICK_LINE) { currentMouseDraggingPoint = e.getPoint(); repaint(); } } @Override public void mouseMoved(MouseEvent e) { // Gets the value of the current logical coordinates of the mouse try { affineTransform.inverseTransform(e.getPoint(), currentMousePointLogic); } catch (Exception ex) { return; } if (Globals.editMode == Constants.EditMode.INPUT_LINE) { if (Globals.lineInputMode == Constants.LineInputMode.DIRECT_V || Globals.lineInputMode == Constants.LineInputMode.ON_V || Globals.lineInputMode == Constants.LineInputMode.OVERLAP_V || Globals.lineInputMode == Constants.LineInputMode.PBISECTOR) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV == null) { if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) { // Arbitrary point on the line when you press the Ctrl OriLine l = pickLine(currentMousePointLogic); if (l != null) { pickCandidateV = new Vector2d(); Vector2d cp = new Vector2d(currentMousePointLogic.x, currentMousePointLogic.y); GeomUtil.DistancePointToSegment(cp, l.p0, l.p1, pickCandidateV); } } } if (pickCandidateV != preV || prePickV != null) { repaint(); } } else if (Globals.lineInputMode == Constants.LineInputMode.COPY_AND_PASTE) { pickCandidateV = this.pickVertex(currentMousePointLogic); repaint(); } else if (Globals.lineInputMode == Constants.LineInputMode.SYMMETRIC_LINE) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV != preV) { repaint(); } } else if (Globals.lineInputMode == Constants.LineInputMode.TRIANGLE_SPLIT) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV != preV) { repaint(); } } else if (Globals.lineInputMode == Constants.LineInputMode.BISECTOR) { if (prePickV == null) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV != preV || prePickV != null) { repaint(); } } else { OriLine preLine = pickCandidateL; pickCandidateL = pickLine(currentMousePointLogic); if (preLine != pickCandidateL) { repaint(); } } } else if (Globals.lineInputMode == Constants.LineInputMode.VERTICAL_LINE) { if (prePickV == null) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV != preV || prePickV != null) { repaint(); } } else { OriLine preLine = pickCandidateL; pickCandidateL = pickLine(currentMousePointLogic); if (preLine != pickCandidateL) { repaint(); } } } else if (Globals.lineInputMode == Constants.LineInputMode.MIRROR) { OriLine preLine = pickCandidateL; pickCandidateL = pickLine(currentMousePointLogic); if (preLine != pickCandidateL) { repaint(); } } else if (Globals.lineInputMode == Constants.LineInputMode.BY_VALUE) { if (Globals.subLineInputMode == Constants.SubLineInputMode.NONE) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV != preV) { repaint(); } } else if (Globals.subLineInputMode == Constants.SubLineInputMode.PICK_LENGTH) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV != preV || prePickV != null) { repaint(); } } else if (Globals.subLineInputMode == Constants.SubLineInputMode.PICK_ANGLE) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV != preV) { repaint(); } } } } else if (Globals.editMode == Constants.EditMode.DELETE_LINE) { OriLine preLine = pickCandidateL; pickCandidateL = pickLine(currentMousePointLogic); if (preLine != pickCandidateL) { repaint(); } } else if (Globals.editMode == Constants.EditMode.PICK_LINE) { OriLine preLine = pickCandidateL; pickCandidateL = pickLine(currentMousePointLogic); if (preLine != pickCandidateL) { repaint(); } } else if (Globals.editMode == Constants.EditMode.ADD_VERTEX) { Object[] line_vertex = new Object[2]; if (pickPointOnLine(currentMousePointLogic, line_vertex)) { pickCandidateV = (Vector2d) line_vertex[1]; repaint(); } else { if (pickCandidateV != null) { pickCandidateV = null; repaint(); } } } else if (Globals.editMode == Constants.EditMode.DELETE_VERTEX) { Vector2d preV = pickCandidateV; pickCandidateV = this.pickVertex(currentMousePointLogic); if (pickCandidateV != preV || prePickV != null) { repaint(); } } else if (Globals.editMode == Constants.EditMode.EDIT_OUTLINE) { pickCandidateV = this.pickVertex(currentMousePointLogic); repaint(); } } @Override public void mouseWheelMoved(MouseWheelEvent e) { double scale_ = (100.0 - e.getWheelRotation() * 5) / 100.0; scale *= scale_; updateAffineTransform(); repaint(); } @Override public void actionPerformed(ActionEvent ae) { } @Override public void componentResized(ComponentEvent arg0) { if (getWidth() <= 0 || getHeight() <= 0) { return; } preSize = getSize(); // Update of the logical coordinates of the center of the screen transX = transX - preSize.width * 0.5 + getWidth() * 0.5; transY = transY - preSize.height * 0.5 + getHeight() * 0.5; // Updating the image buffer bufferImage = createImage(getWidth(), getHeight()); bufferg = (Graphics2D) bufferImage.getGraphics(); updateAffineTransform(); repaint(); } @Override public void componentMoved(ComponentEvent arg0) { // TODO Auto-generated method stub } @Override public void componentShown(ComponentEvent arg0) { // TODO Auto-generated method stub } @Override public void componentHidden(ComponentEvent arg0) { // TODO Auto-generated method stub } }