public void prect(Coord c, Coord ul, Coord br, double a) { st.set(cur2d); apply(); gl.glEnable(GL2.GL_POLYGON_SMOOTH); gl.glBegin(GL.GL_TRIANGLE_FAN); vertex(c); vertex(c.add(0, ul.y)); double p2 = Math.PI / 2; all: { float tc; tc = (float) (Math.tan(a) * -ul.y); if ((a > p2) || (tc > br.x)) { vertex(c.x + br.x, c.y + ul.y); } else { vertex(c.x + tc, c.y + ul.y); break all; } tc = (float) (Math.tan(a - (Math.PI / 2)) * br.x); if ((a > p2 * 2) || (tc > br.y)) { vertex(c.x + br.x, c.y + br.y); } else { vertex(c.x + br.x, c.y + tc); break all; } tc = (float) (-Math.tan(a - Math.PI) * br.y); if ((a > p2 * 3) || (tc < ul.x)) { vertex(c.x + ul.x, c.y + br.y); } else { vertex(c.x + tc, c.y + br.y); break all; } tc = (float) (-Math.tan(a - (3 * Math.PI / 2)) * -ul.x); if ((a > p2 * 4) || (tc < ul.y)) { vertex(c.x + ul.x, c.y + ul.y); } else { vertex(c.x + ul.x, c.y + tc); break all; } tc = (float) (Math.tan(a) * -ul.y); vertex(c.x + tc, c.y + ul.y); } gl.glEnd(); gl.glDisable(GL2.GL_POLYGON_SMOOTH); checkerr(); }
protected void transformInverse(int x, int y, float[] out) { float theta, t; float m, xmax, ymax; float r = 0; switch (type) { case RECT_TO_POLAR: theta = 0; if (x >= centreX) { if (y > centreY) { theta = ImageMath.PI - (float) Math.atan(((float) (x - centreX)) / ((float) (y - centreY))); r = (float) Math.sqrt(sqr(x - centreX) + sqr(y - centreY)); } else if (y < centreY) { theta = (float) Math.atan(((float) (x - centreX)) / ((float) (centreY - y))); r = (float) Math.sqrt(sqr(x - centreX) + sqr(centreY - y)); } else { theta = ImageMath.HALF_PI; r = x - centreX; } } else if (x < centreX) { if (y < centreY) { theta = ImageMath.TWO_PI - (float) Math.atan(((float) (centreX - x)) / ((float) (centreY - y))); r = (float) Math.sqrt(sqr(centreX - x) + sqr(centreY - y)); } else if (y > centreY) { theta = ImageMath.PI + (float) Math.atan(((float) (centreX - x)) / ((float) (y - centreY))); r = (float) Math.sqrt(sqr(centreX - x) + sqr(y - centreY)); } else { theta = 1.5f * ImageMath.PI; r = centreX - x; } } if (x != centreX) m = Math.abs(((float) (y - centreY)) / ((float) (x - centreX))); else m = 0; if (m <= ((float) height / (float) width)) { if (x == centreX) { xmax = 0; ymax = centreY; } else { xmax = centreX; ymax = m * xmax; } } else { ymax = centreY; xmax = ymax / m; } out[0] = (width - 1) - (width - 1) / ImageMath.TWO_PI * theta; out[1] = height * r / radius; break; case POLAR_TO_RECT: theta = x / width * ImageMath.TWO_PI; float theta2; if (theta >= 1.5f * ImageMath.PI) theta2 = ImageMath.TWO_PI - theta; else if (theta >= ImageMath.PI) theta2 = theta - ImageMath.PI; else if (theta >= 0.5f * ImageMath.PI) theta2 = ImageMath.PI - theta; else theta2 = theta; t = (float) Math.tan(theta2); if (t != 0) m = 1.0f / t; else m = 0; if (m <= ((float) (height) / (float) (width))) { if (theta2 == 0) { xmax = 0; ymax = centreY; } else { xmax = centreX; ymax = m * xmax; } } else { ymax = centreY; xmax = ymax / m; } r = radius * (float) (y / (float) (height)); float nx = -r * (float) Math.sin(theta2); float ny = r * (float) Math.cos(theta2); if (theta >= 1.5f * ImageMath.PI) { out[0] = (float) centreX - nx; out[1] = (float) centreY - ny; } else if (theta >= Math.PI) { out[0] = (float) centreX - nx; out[1] = (float) centreY + ny; } else if (theta >= 0.5 * Math.PI) { out[0] = (float) centreX + nx; out[1] = (float) centreY + ny; } else { out[0] = (float) centreX + nx; out[1] = (float) centreY - ny; } break; case INVERT_IN_CIRCLE: float dx = x - centreX; float dy = y - centreY; float distance2 = dx * dx + dy * dy; out[0] = centreX + centreX * centreX * dx / distance2; out[1] = centreY + centreY * centreY * dy / distance2; break; } }
/** * Gets a list of Point2D objects that lie within pixels in a rectangle and along a line. * * @param searchRect the rectangle * @param x0 the x-component of a point on the line * @param y0 the y-component of a point on the line * @param slope the slope of the line * @return a list of Point2D */ public ArrayList<Point2D> getSearchPoints( Rectangle searchRect, double x0, double y0, double theta) { double slope = -Math.tan(theta); // create line to search along Line2D line = new Line2D.Double(); if (slope > LARGE_NUMBER) { line.setLine(x0, y0, x0, y0 + 1); } else if (slope < 1 / LARGE_NUMBER) { line.setLine(x0, y0, x0 + 1, y0); } else { line.setLine(x0, y0, x0 + 1, y0 + slope); } // create intersection points (to set line ends) Point2D p1 = new Point2D.Double(); Point2D p2 = new Point2D.Double(Double.NaN, Double.NaN); Point2D p = p1; boolean foundBoth = false; double d = searchRect.x; Object[] data = getDistanceAndPointAtX(line, d); if (data != null) { p.setLocation((Point2D) data[1]); if (p.getY() >= searchRect.y && p.getY() <= searchRect.y + searchRect.height) { // line end is left edge p = p2; } } d += searchRect.width; data = getDistanceAndPointAtX(line, d); if (data != null) { p.setLocation((Point2D) data[1]); if (p.getY() >= searchRect.y && p.getY() <= searchRect.y + searchRect.height) { // line end is right edge if (p == p1) p = p2; else foundBoth = true; } } if (!foundBoth) { d = searchRect.y; data = getDistanceAndPointAtY(line, d); if (data != null) { p.setLocation((Point2D) data[1]); if (p.getX() >= searchRect.x && p.getX() <= searchRect.x + searchRect.width) { // line end is top edge if (p == p1) p = p2; else if (!p1.equals(p2)) foundBoth = true; } } } if (!foundBoth) { d += searchRect.height; data = getDistanceAndPointAtY(line, d); if (data != null) { p.setLocation((Point2D) data[1]); if (p.getX() >= searchRect.x && p.getX() <= searchRect.x + searchRect.width) { // line end is bottom edge if (p == p2 && !p1.equals(p2)) foundBoth = true; } } } // if both line ends have been found, use line to find pixels to search if (foundBoth) { // set line ends to intersections line.setLine(p1, p2); if (p1.getX() > p2.getX()) { line.setLine(p2, p1); } // find pixel intersections that fall along the line int xMin = (int) Math.ceil(Math.min(p1.getX(), p2.getX())); int xMax = (int) Math.floor(Math.max(p1.getX(), p2.getX())); int yMin = (int) Math.ceil(Math.min(p1.getY(), p2.getY())); int yMax = (int) Math.floor(Math.max(p1.getY(), p2.getY())); // collect intersections in TreeMap sorted by position along line TreeMap<Double, Point2D> intersections = new TreeMap<Double, Point2D>(); for (int x = xMin; x <= xMax; x++) { Object[] next = getDistanceAndPointAtX(line, x); intersections.put((Double) next[0], (Point2D) next[1]); } for (int y = yMin; y <= yMax; y++) { Object[] next = getDistanceAndPointAtY(line, y); intersections.put((Double) next[0], (Point2D) next[1]); } p = null; // create array of search points that are midway between intersections ArrayList<Point2D> searchPts = new ArrayList<Point2D>(); for (Double key : intersections.keySet()) { Point2D next = intersections.get(key); if (p != null) { double x = (p.getX() + next.getX()) / 2 - searchRect.x; double y = (p.getY() + next.getY()) / 2 - searchRect.y; p.setLocation(x, y); searchPts.add(p); } p = next; } return searchPts; } return null; }
public void skewY(float angle) { g2.shear(0, Math.tan(angle)); }
public void skewX(float angle) { g2.shear(Math.tan(angle), 0); }