/** * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>, * <code>nohref</code> Attribute for the specified figure and shape. * * @return Returns true, if the polygon is inside of the image bounds. */ private boolean writePolyAttributes(IXMLElement elem, SVGFigure f, Shape shape) { AffineTransform t = TRANSFORM.getClone(f); if (t == null) { t = drawingTransform; } else { t.preConcatenate(drawingTransform); } StringBuilder buf = new StringBuilder(); float[] coords = new float[6]; GeneralPath path = new GeneralPath(); for (PathIterator i = shape.getPathIterator(t, 1.5f); ! i.isDone(); i.next()) { switch (i.currentSegment(coords)) { case PathIterator.SEG_MOVETO : if (buf.length() != 0) { throw new IllegalArgumentException("Illegal shape "+shape); } if (buf.length() != 0) { buf.append(','); } buf.append((int) coords[0]); buf.append(','); buf.append((int) coords[1]); path.moveTo(coords[0], coords[1]); break; case PathIterator.SEG_LINETO : if (buf.length() != 0) { buf.append(','); } buf.append((int) coords[0]); buf.append(','); buf.append((int) coords[1]); path.lineTo(coords[0], coords[1]); break; case PathIterator.SEG_CLOSE : path.closePath(); break; default : throw new InternalError("Illegal segment type "+i.currentSegment(coords)); } } elem.setAttribute("shape", "poly"); elem.setAttribute("coords", buf.toString()); writeHrefAttribute(elem, f); return path.intersects(new Rectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height)); }
@Override public void keyPressed(KeyEvent evt) { Figure f = getOwner(); if (f.isTransformable()) { AffineTransform tx = new AffineTransform(); switch (evt.getKeyCode()) { case KeyEvent.VK_UP: tx.translate(0, -1); evt.consume(); break; case KeyEvent.VK_DOWN: tx.translate(0, +1); evt.consume(); break; case KeyEvent.VK_LEFT: tx.translate(-1, 0); evt.consume(); break; case KeyEvent.VK_RIGHT: tx.translate(+1, 0); evt.consume(); break; } f.willChange(); f.transform(tx); f.changed(); fireUndoableEditHappened(new TransformEdit(f, tx)); } }
/** * Code to paint the WhiteboardShapeRect. * * @param g graphics context * @param t 2D affine transformation */ public void paintShape(Graphics2D g, AffineTransform t) { double x = point.getX(); double y = point.getY(); g.setStroke(new BasicStroke(this.getThickness(), BasicStroke.CAP_ROUND, BasicStroke.CAP_ROUND)); Point2D w0 = new Point2D.Double(x, y); Point2D v0 = t.transform(w0, null); int x0 = (int) v0.getX(); int y0 = (int) v0.getY(); Point2D w1 = new Point2D.Double(x + width, y + height); Point2D v1 = t.transform(w1, null); int xWidth = (int) v1.getX() - x0; int yHeight = (int) v1.getY() - y0; g.setColor(Color.getColor("", this.getColor())); if (fill) { g.fillRect(x0, y0, xWidth, yHeight); } else { g.drawRect(x0, y0, xWidth, yHeight); } }
/** * WhiteboardShapeRect constructor. * * @param id String that uniquely identifies this WhiteboardShapeRect * @param thickness number of pixels that this object (or its border) should be thick * @param color WhiteboardShapeRect's color (or rather it's border) * @param point coordinates of this object. * @param width width value of this object (in pixel) * @param height height value of this object (in pixel) * @param fill True is filled, false is unfilled * @param transform 2D affine transformation */ public WhiteboardShapeRect( String id, int thickness, Color color, WhiteboardPoint point, double width, double height, boolean fill, AffineTransform transform) { super(id); Point2D v0 = new Point2D.Double(point.getX(), point.getY()); Point2D w0 = transform.transform(v0, null); double x = w0.getX(); double y = w0.getY(); point.setX(x); point.setY(y); Point2D v1 = new Point2D.Double(x + width, y + height); Point2D w1 = transform.transform(v1, null); double transformedWidth = w1.getX() - x; double transformedHeight = w1.getY() - y; this.initShape(thickness, color, point, transformedWidth, transformedHeight, fill); }
@Override public void trackEnd(Point anchor, Point lead, int modifiersEx) { if (getOwner().isTransformable()) { AffineTransform tx = new AffineTransform(); tx.translate(lead.x - anchor.x, lead.y - anchor.y); fireUndoableEditHappened(new TransformEdit(getOwner(), tx)); } }
public void drawScaledImage(BufferedImage im, int x, int y, int w, int h) { float scaleX = w * 1.0f / im.getWidth(); float scaleY = h * 1.0f / im.getHeight(); AffineTransform tx = new AffineTransform(); tx.scale(scaleX, scaleY); BufferedImageOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR); drawImage(im, op, x, y); }
/** * Gets the mark for the specified panel. * * @param trackerPanel the tracker panel * @return the mark */ protected Mark getMark(TrackerPanel trackerPanel) { Mark mark = marks.get(trackerPanel); TPoint selection = null; if (mark == null) { selection = trackerPanel.getSelectedPoint(); Point p = null; valid = true; // assume true for (int n = 0; n < points.length; n++) { if (!valid) continue; // determine if point is valid (ie not NaN) valid = valid && !Double.isNaN(points[n].getX()) && !Double.isNaN(points[n].getY()); screenPoints[n] = points[n].getScreenPosition(trackerPanel); if (valid && selection == points[n]) p = screenPoints[n]; } mark = footprint.getMark(screenPoints); if (p != null) { // point is selected, so draw selection shape transform.setToTranslation(p.x, p.y); int scale = FontSizer.getIntegerFactor(); if (scale > 1) { transform.scale(scale, scale); } final Color color = footprint.getColor(); final Mark stepMark = mark; final Shape selectedShape = transform.createTransformedShape(selectionShape); mark = new Mark() { public void draw(Graphics2D g, boolean highlighted) { stepMark.draw(g, false); Paint gpaint = g.getPaint(); g.setPaint(color); g.fill(selectedShape); g.setPaint(gpaint); } public Rectangle getBounds(boolean highlighted) { Rectangle bounds = selectedShape.getBounds(); bounds.add(stepMark.getBounds(false)); return bounds; } }; } final Mark theMark = mark; mark = new Mark() { public void draw(Graphics2D g, boolean highlighted) { if (!valid) return; theMark.draw(g, false); } public Rectangle getBounds(boolean highlighted) { return theMark.getBounds(highlighted); } }; marks.put(trackerPanel, mark); } return mark; }
private AffineTransform makeTransform(Object o) { AffineTransform r = (AffineTransform) ((AffineTransform) o).clone(); // System.out.println("r:"+r); if (origTransform != null) { AffineTransform r2 = (AffineTransform) origTransform.clone(); // System.out.println("r2:"+r2); r2.concatenate(r); r = r2; } return r; }
/** * synchronize frame shape and location (TextLayout only) ; this is called by syncShape(), so that * subclasser might override easily when only rectangular shapes are availables. */ protected void syncFrame() { PicText te = (PicText) element; if (!te.isFramed()) { return; } AffineTransform tr = new AffineTransform(); // maps Image coordinates to Model coordinates (see paint) tr.setToIdentity(); // reset PicPoint anchor = te.getCtrlPt(TextEditable.P_ANCHOR, ptBuf); tr.rotate(getRotation(), anchor.x, anchor.y); // rotate along P_ANCHOR ! shape = tr.createTransformedShape(te.getShapeOfFrame()); }
/** * Zoom, preserving the center point on the screen. (When we draw, the center point may be moved * in order to maximize the amount of image seen on screen.) * */ void adjustZoom(double z, Point2D cp) { if (cp == null) cp = new Point2D.Double(getWidth() / 2, getHeight() / 2); Point2D cxt = componentToImage(cp); double tx = cp.getX() - cxt.getX() * z; double ty = cp.getY() - cxt.getY() * z; t = new AffineTransform(); t.translate(tx, ty); t.scale(z, z); fit = false; repaint(); }
@Override public void trackStep(Point anchor, Point lead, int modifiersEx) { Figure f = getOwner(); if (f.isTransformable()) { Point2D.Double newPoint = view.getConstrainer().constrainPoint(view.viewToDrawing(lead)); AffineTransform tx = new AffineTransform(); tx.translate(newPoint.x - oldPoint.x, newPoint.y - oldPoint.y); f.willChange(); f.transform(tx); f.changed(); oldPoint = newPoint; } }
void draw(Graphics2D g) { // toX/toY is tip of arrow and fx/fy is a point on the line - // fx/fy is used to determine direction & angle AffineTransform at = AffineTransform.getTranslateInstance(toX, toY); int b = 9; double theta = Math.toRadians(20); // The idea of using a GeneralPath is so we can // create the (three lines that make up the) arrow // (only) one time and then use AffineTransform to // place it anywhere we want. GeneralPath path = new GeneralPath(); // distance between line and the arrow mark <** not ** // Start a new line segment from the position of (0,0). path.moveTo(0, 0); // Create one of the two arrow head lines. int x = (int) (-b * Math.cos(theta)); int y = (int) (b * Math.sin(theta)); path.lineTo(x, y); // distance between line and the arrow mark <** not ** // Make the other arrow head line. int x2 = (int) (-b * Math.cos(-theta)); int y2 = (int) (b * Math.sin(-theta)); // path.moveTo(0,0); path.lineTo(x2, y2); path.closePath(); // theta is in radians double s, t; s = toY - fy; // calculate slopes. t = toX - fx; if (t != 0) { s = s / t; theta = Math.atan(s); if (t < 0) theta += Math.PI; } else if (s < 0) theta = -(Math.PI / 2); else theta = Math.PI / 2; at.rotate(theta); // at.rotate(theta,toX,toY); Shape shape = at.createTransformedShape(path); if (checkStatus == Status.UNCHECKED) g.setColor(Color.BLACK); else if (checkStatus == Status.COMPATIBLE) g.setColor(FOREST_GREEN); else g.setColor(ORANGE_RED); g.fill(shape); g.draw(shape); }
@Override public void transform(AffineTransform tx) { if (get(TRANSFORM) != null || (tx.getType() & (AffineTransform.TYPE_TRANSLATION)) != tx.getType()) { if (get(TRANSFORM) == null) { TRANSFORM.setClone(this, tx); } else { AffineTransform t = TRANSFORM.getClone(this); t.preConcatenate(tx); set(TRANSFORM, t); } } else { super.transform(tx); } }
public void mouseDragged(MouseEvent e) { int mods = e.getModifiersEx(); Point dragEnd = e.getPoint(); boolean shift = (mods & MouseEvent.SHIFT_DOWN_MASK) > 0; boolean ctrl = (mods & MouseEvent.CTRL_DOWN_MASK) > 0; boolean alt = shift & ctrl; ctrl = ctrl & (!alt); shift = shift & (!alt); boolean nomods = !(shift | ctrl | alt); if (dragBegin == null) dragBegin = dragEnd; nodrag = false; if ((mods & InputEvent.BUTTON3_DOWN_MASK) > 0 || true) { double dx = dragEnd.getX() - dragBegin.getX(); double dy = dragEnd.getY() - dragBegin.getY(); synchronized (JImage.this) { t.preConcatenate(AffineTransform.getTranslateInstance(dx, dy)); } dragBegin = dragEnd; repaint(); } }
/** * This implementation calls <code>super.hitTest</code> and returns the result if non-null (this * should be a HitInfo.Point), then returns a HitInfo.Interior if the mouse-click occured inside * the text bound (as defined by text layout) * * @return a HitInfo corresponding to the given mouse-event */ public HitInfo hitTest(PEMouseEvent e) { // from Bitmap: if (image != null) { if (getBounds().contains(e.getPicPoint())) { return new HitInfo.Interior((PicText) element, e); } return null; } // from TextLayout: if (!getBounds().contains(e.getPicPoint())) return null; PicText te = (PicText) element; // recompute textlayout b-box, but store it in a temporary field ! Rectangle2D tb = textLayout.getBounds(); Shape text_bounds = text2ModelTr.createTransformedShape(tb); if (text_bounds.contains(e.getPicPoint())) { // [SR:pending] for the hitInfo to be reliable, getPicPoint() should first be transformed by // inverse text2ModelTr ! (especially when rotationAngle != 0) TextHitInfo thi = textLayout.hitTestChar( (float) (e.getPicPoint().x - strx), (float) (e.getPicPoint().y - stry)); // guaranteed to return a non-null thi return new HitInfo.Text((PicText) element, thi, e); } // test hit on textlayout's bounding rectangle : // else if (bounds.contains(e.getPicPoint())) return new HitInfo.Interior(element,e); return null; }
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; AffineTransform trans = new AffineTransform(); int width = getSize().width; int height = getSize().height; g2d.setColor(Color.BLACK); g2d.fillRect(0, 0, width, height); trans.setTransform(identity); trans.scale(scale, scale); g2d.drawImage(image, trans, this); }
/** * Code to paint the specific shape * * @param w2v 2D affine transform * @param g graphics context */ public void paintShape(Graphics2D g, AffineTransform w2v) { double x = startPoint.getX(); double y = startPoint.getY(); double xEnd = endPoint.getX(); double yEnd = endPoint.getY(); g.setStroke(new BasicStroke(this.getThickness(), BasicStroke.CAP_ROUND, BasicStroke.CAP_ROUND)); Point2D v0 = w2v.transform(new Point2D.Double(x, y), null); int ix = (int) v0.getX(); int iy = (int) v0.getY(); Point2D v1 = w2v.transform(new Point2D.Double(xEnd, yEnd), null); g.drawLine(ix, iy, (int) v1.getX(), (int) v1.getY()); }
public void setFontSize(float size) { // FONT_SIZE.basicSet(this, new Double(size)); Point2D.Double p = new Point2D.Double(0, size); AffineTransform tx = TRANSFORM.get(this); if (tx != null) { try { tx.inverseTransform(p, p); Point2D.Double p0 = new Point2D.Double(0, 0); tx.inverseTransform(p0, p0); p.y -= p0.y; } catch (NoninvertibleTransformException ex) { ex.printStackTrace(); } } FONT_SIZE.set(this, Math.abs(p.y)); }
public void addGlyph(GlyphData gv, float x, float y) { AffineTransform at = AffineTransform.getTranslateInstance(x, y); PathIterator pi = gv.gp.getPathIterator(at); float[] coords = new float[6]; while (!pi.isDone()) { int type = pi.currentSegment(coords); switch (type) { case PathIterator.SEG_MOVETO: moveTo(coords[0], coords[1]); break; case PathIterator.SEG_LINETO: lineTo(coords[0], coords[1]); break; case PathIterator.SEG_CUBICTO: curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); break; case PathIterator.SEG_CLOSE: closePath(); break; default: System.out.println("Unknown path type: " + type); break; } pi.next(); } }
private static MeshCoords transformSector(AffineTransform transform, Sector sector) { java.awt.geom.Point2D p = new java.awt.geom.Point2D.Double(); java.awt.geom.Point2D ll = new java.awt.geom.Point2D.Double(); java.awt.geom.Point2D ur = new java.awt.geom.Point2D.Double(); p.setLocation(sector.getMinLongitude().degrees, sector.getMinLatitude().degrees); transform.transform(p, ll); p.setLocation(sector.getMaxLongitude().degrees, sector.getMaxLatitude().degrees); transform.transform(p, ur); return new MeshCoords( (float) ur.getY(), // Top (float) ll.getX(), // Left (float) ll.getY(), // Bottom (float) ur.getX()); // Right }
public float getFontSize() { // return FONT_SIZE.get(this).floatValue(); Point2D.Double p = new Point2D.Double(0, FONT_SIZE.get(this)); AffineTransform tx = TRANSFORM.get(this); if (tx != null) { tx.transform(p, p); Point2D.Double p0 = new Point2D.Double(0, 0); tx.transform(p0, p0); p.y -= p0.y; /* try { tx.inverseTransform(p, p); } catch (NoninvertibleTransformException ex) { ex.printStackTrace(); }*/ } return (float) Math.abs(p.y); }
public void vec2FieldMagnitude(Field field, AffineTransform ftoi) { AffineTransform itof = null; try { itof = ftoi.createInverse(); } catch (NoninvertibleTransformException niv) { TDebug.println(0, "NoninvertibleTransformException: " + niv); } Vector3d v = new Vector3d(); Point2D.Double p = new Point2D.Double(); for (int j = 0, k = 0; j < height; ++j) for (int i = 0; i < width; ++i, ++k) { p.x = i; p.y = j; itof.transform(p, p); v = field.get(p.x, p.y, 0.0); f[k] = (float) Math.sqrt(v.x * v.x + v.y * v.y); } }
public void vec2FieldZero(Field field, AffineTransform ftoi) { AffineTransform itof = null; try { itof = ftoi.createInverse(); } catch (NoninvertibleTransformException niv) { TDebug.println(0, "NoninvertibleTransformException: " + niv); } Vector3d v = new Vector3d(); Point2D.Double p = new Point2D.Double(); for (int j = 0, k = 0; j < height; ++j) for (int i = 0; i < width; ++i, ++k) { p.x = i; p.y = j; itof.transform(p, p); v = field.get(p.x, p.y, 0.0); if ((v.x == 0.0) && (v.y == 0.0)) f[k] = 1.0f; else f[k] = 0.0f; } }
/** Synchronizes bounding box with the model ; */ protected void syncBounds() { PicText te = (PicText) element; // [pending] Il faut tenir compte de la rotation ! Rectangle2D latexBB = null; // BB relative to latex dimensions (including rotation) (without frame) Rectangle2D textLayoutBB = null; // BB relative to textLayout dimensions (including rotation) (without frame) Rectangle2D textBB = null; // BB of the text (including rotation), without frame if (areDimensionsComputed) { // compute latexBB Rectangle2D nonRotated = new Rectangle2D.Double( te.getLeftX(), te.getBottomY(), te.getWidth(), te.getHeight() + te.getDepth()); AffineTransform tr = new AffineTransform(); // maps Image coordinates to Model coordinates (see paint) tr.setToIdentity(); // reset PicPoint anchor = te.getCtrlPt(TextEditable.P_ANCHOR, ptBuf); tr.rotate(getRotation(), anchor.x, anchor.y); // rotate along P_ANCHOR ! latexBB = tr.createTransformedShape(nonRotated).getBounds2D(); } if (image == null) { // compute textLayoutBB Rectangle2D nonRotated = textLayout.getBounds(); textLayoutBB = text2ModelTr.createTransformedShape(nonRotated).getBounds2D(); } // use textLayoutBB or latexBB or their union if (image != null) textBB = latexBB; else { if (!areDimensionsComputed) textBB = textLayoutBB; else { textBB = latexBB.createUnion(textLayoutBB); } } // union with frame BB if (te.isFramed()) { super.syncBounds(); // update bounds of the frame if necessary Rectangle2D.union(super.bounds, textBB, this.bounds); } else this.bounds = textBB; }
public Point2D componentToImage(Point2D p) { Point2D tp = null; try { tp = t.inverseTransform(p, null); } catch (NoninvertibleTransformException ex) { // can't happen. } return tp; }
/** * WhiteboardShapeLine constructor * * @param id String that uniquely identifies this WhiteboardObject. * @param t number of pixels that this object (or its border) * @param c WhiteboardShapeLine's color (or rather it's border) * @param startPoint the start coordinates of this line. * @param endPoint the end coordinates of this line. * @param v2w 2D affine transform */ public WhiteboardShapeLine( String id, int t, Color c, WhiteboardPoint startPoint, WhiteboardPoint endPoint, AffineTransform v2w) { super(id); this.setThickness(t); setColor(c); Point2D v0 = new Point2D.Double(startPoint.getX(), startPoint.getY()); Point2D w0 = v2w.transform(v0, null); this.startPoint = new WhiteboardPoint(w0.getX(), w0.getY()); Point2D v1 = new Point2D.Double(endPoint.getX(), endPoint.getY()); Point2D w1 = v2w.transform(v1, null); this.endPoint = new WhiteboardPoint(w1.getX(), w1.getY()); }
/** * Transforms the figure. * * @param tx the transformation. */ public void transform(AffineTransform tx) { if (TRANSFORM.get(this) != null || tx.getType() != (tx.getType() & AffineTransform.TYPE_TRANSLATION)) { if (TRANSFORM.get(this) == null) { TRANSFORM.basicSet(this, (AffineTransform) tx.clone()); } else { AffineTransform t = TRANSFORM.getClone(this); t.preConcatenate(tx); TRANSFORM.basicSet(this, t); } } else { for (int i = 0; i < coordinates.length; i++) { tx.transform(coordinates[i], coordinates[i]); } if (FILL_GRADIENT.get(this) != null && !FILL_GRADIENT.get(this).isRelativeToFigureBounds()) { Gradient g = FILL_GRADIENT.getClone(this); g.transform(tx); FILL_GRADIENT.basicSet(this, g); } if (STROKE_GRADIENT.get(this) != null && !STROKE_GRADIENT.get(this).isRelativeToFigureBounds()) { Gradient g = STROKE_GRADIENT.getClone(this); g.transform(tx); STROKE_GRADIENT.basicSet(this, g); } } invalidate(); }
/** * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>, * <code>nohref</code> Attribute for the specified figure and ellipse. * * @return Returns true, if the circle is inside of the image bounds. */ private boolean writeCircleAttributes(IXMLElement elem, SVGFigure f, Ellipse2D.Double ellipse) { AffineTransform t = TRANSFORM.getClone(f); if (t == null) { t = drawingTransform; } else { t.preConcatenate(drawingTransform); } if ((t.getType() & (AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION)) == t.getType() && ellipse.width == ellipse.height ) { Point2D.Double start = new Point2D.Double(ellipse.x, ellipse.y); Point2D.Double end = new Point2D.Double(ellipse.x + ellipse.width, ellipse.y + ellipse.height); t.transform(start, start); t.transform(end, end); ellipse.x = Math.min(start.x, end.x); ellipse.y = Math.min(start.y, end.y); ellipse.width = Math.abs(start.x - end.x); ellipse.height = Math.abs(start.y - end.y); elem.setAttribute("shape", "circle"); elem.setAttribute("coords", (int) (ellipse.x + ellipse.width / 2d)+","+ (int) (ellipse.y + ellipse.height / 2d)+","+ (int) (ellipse.width / 2d) ); writeHrefAttribute(elem, f); return bounds.intersects(ellipse.getBounds()); } else { return writePolyAttributes(elem, f, (Shape) ellipse); } }
/** * All other write methods delegate their work to here. */ public void write(OutputStream out, java.util.List<Figure> figures) throws IOException { Rectangle2D.Double drawingRect = null; for (Figure f : figures) { if (drawingRect == null) { drawingRect = f.getBounds(); } else { drawingRect.add(f.getBounds()); } } AffineTransform drawingTransform = new AffineTransform(); drawingTransform.translate( -Math.min(0, drawingRect.x), -Math.min(0, drawingRect.y) ); write(out, figures, drawingTransform, new Dimension( (int) (Math.abs(drawingRect.x) + drawingRect.width), (int) (Math.abs(drawingRect.y) + drawingRect.height)) ); }
/* Draws the ball at its current position */ public void draw(Graphics2D g) { double imageWidth = img.getWidth(parent); double imageHeight = img.getHeight(parent); // translate image such that its centred on its actual position objectTransform.setToTranslation( (double) pos_x - imageWidth / 2, (double) pos_y - imageHeight / 2); // // this rotates the planet! // objectTransform.rotate(Math.PI/800,50.0,51.0); g.setTransform(new AffineTransform()); g.drawImage(img, objectTransform, parent); }