/** * Detects mouse being release. This completes the rectangle representing the new complex plane. * It draws the selected rectangle first, redraws the image and repaints the screen. */ @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub /* * currSXMax = e.getX(); currSYMax = e.getY(); * * System.out.printf("currSXMax: %f, currSYMax: %f\n ",currSXMax,currSYMax * ); */ endX = e.getX(); endY = e.getY(); // DEBUG // System.out.printf("endX: %f, endY: %f\n ",endX,endY); currSXMin = Math.min(startX, endX); currSYMin = Math.min(startY, endY); currSXMax = Math.max(startX, endX); currSYMax = Math.max(startY, endY); // Graphics g = this.getGraphics(); Graphics g = this.img.getGraphics(); g.setColor(new Color(1, 1, 1, 0.7f)); // DEBUG // System.out.printf("Recgtangle(%d, %d, %d, %d)\n", (int) currSXMin, // (int) currSYMin, (int) (currSXMax - currSXMin), (int) (currSYMax - // currSYMin)); g.fillRect( (int) currSXMin, (int) currSYMin, (int) (currSXMax - currSXMin), (int) (currSYMax - currSYMin)); Point2D.Double screenPoint = new Point2D.Double(); Point2D P = null; ScreenToWorldPointConverter converter = null; try { converter = new ScreenToWorldPointConverter( currWXMin, currWYMin, currWXMax, currWYMax, 0, 0, width - 1, height - 1); } catch (Exception ex) { throw new IllegalStateException(ex); } screenPoint.setLocation(currSXMin, currSYMin); P = converter.getWorldCoordinates(screenPoint); currWXMin = P.getX(); currWYMin = P.getY(); screenPoint.setLocation(currSXMax, currSYMax); P = converter.getWorldCoordinates(screenPoint); currWXMax = P.getX(); currWYMax = P.getY(); redrawImage(); repaint(); }
/** Redraws the image. */ private void redrawImage() { ScreenToWorldPointConverter converter = null; try { converter = new ScreenToWorldPointConverter( currWXMin, currWYMin, currWXMax, currWYMax, 0, 0, width - 1, height - 1); } catch (Exception e) { throw new IllegalStateException(e); } Point2D P = null; Point2D.Double screenPoint = new Point2D.Double(); ComplexNumber C = null; Color theColor = null; int colorIndex = 0; for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { screenPoint.setLocation(i, j); P = converter.getWorldCoordinates(screenPoint); C = new ComplexNumber(new RealNumber(P.getX()), new RealNumber(P.getY())); colorIndex = Mandelbrot.divergenceIndex(C); if (colorIndex < 0) { theColor = Color.black; } else { theColor = Mandelbrot.getColor(colorIndex); } img.paintPixel(i, j, theColor.getRGB()); } } }
/** @param override true if should kill even if invulerable, false if not */ public void kill(boolean override) { if (!override) { if (star || invulerable || piped) return; } deathPos.setLocation(pos); if (deathPos.y < 0) { deathPos.y = 0; } if (metal) { metal = false; startInvulnerable(); invulerableTime = 3000 / 15; Point2D.Double v = new Point2D.Double(Math.random() * 8 - 4, Math.random() * 4 + 7); TMetalCap cap = new TMetalCap(); cap.setPos(pos.x, pos.y); cap.kill(v); this.addSpawn(cap); return; } cape = false; dead = true; numBullets = 0; falling = false; acc = new Point2D.Double(); vel = new Point2D.Double(); deadTime = 25; }
@Override public void zoomOutButtonHit() { if (zoomLevel < 5) { zoomLevel++; double x = viewPoint.getX() + viewWidth / 2; double y = viewPoint.getY() + viewWidth / 2; viewWidth = viewWidth * 2; x = x - viewWidth / 2; y = y - viewWidth / 2; if (x < 0) { x = 0; } else if (x + viewWidth > 2048) { x = x - (x + viewWidth - 2048); } if (y < 0) { y = 0; } else if (y + viewWidth > 2048) { y = y - (y + viewWidth - 2048); } viewPoint.setLocation(x, y); setChanged(); notifyObservers(); } }
@Override public void vScrollbarChanged(int value) { if (value != viewPoint.getY()) { viewPoint.setLocation(viewPoint.getX(), value); setChanged(); notifyObservers(); } }
@Override public void mouseDragged(MouseEvent e, CS355Drawing model, Color c) { // Get shape at saved index from model and verify it is a circle Shape shape = model.getShape(this.index); if (!(shape instanceof cs355.model.drawing.Circle)) { GUIFunctions.printf( "Invalid shape - expected cs355.model.drawing.Circle at index %d", this.index); return; } // Cast the shape to a circle and save the new coordinates Circle circle = (Circle) shape; // Initialize new center coordinates to initial coordinates Point2D.Double center = new Point2D.Double(); center.setLocation(this.initialCoordinates); // Get current pointer coordinates Point2D.Double currentCoordinates = new Point2D.Double(); currentCoordinates.setLocation(e.getPoint()); // Find difference between pointer and initial coordinates to get correct orientation double xDifference = currentCoordinates.getX() - initialCoordinates.getX(); double yDifference = currentCoordinates.getY() - initialCoordinates.getY(); // Get radius double radius = Math.min(Math.abs(xDifference), Math.abs(yDifference)) / 2.0; // Get unit vectors for the differences to preserve sign double xDirection = xDifference / Math.abs(xDifference); double yDirection = yDifference / Math.abs(yDifference); // Calculate position of the center of the circle center.x = this.initialCoordinates.getX() + (xDirection * radius); center.y = this.initialCoordinates.getY() + (yDirection * radius); // Set the new parameters circle.setCenter(center); circle.setRadius(radius); }
@Override public void mousePressed(MouseEvent e, CS355Drawing model, Color c) { // Set initial coordinates initialCoordinates.setLocation(e.getPoint()); // Create new line Circle circle = new Circle(c, initialCoordinates, 0.0); // Add line to model and save index this.index = model.addShape(circle); }
@Override public void setBounds(Point2D.Double anchor, Point2D.Double lead) { Point2D.Double near = new Point2D.Double(-1000, -1000); Point2D.Double min = new Point2D.Double(); Point2D.Double max = new Point2D.Double(); if (anchor.distance(near) < lead.distance(near)) { min.setLocation(anchor); max.setLocation(anchor.getX(), lead.getY()); } else { min.setLocation(anchor.getX(), lead.getY()); max.setLocation(anchor); } if (rec == null) { rec = new Rectangle2D.Double(); } rec.setRect(min.getX(), min.getY(), profileWidth, max.getY() - min.getY()); createLine(); }
@Override public void zoomInButtonHit() { if (zoomLevel > 1) { zoomLevel--; double x = viewPoint.getX() + viewWidth / 2; double y = viewPoint.getY() + viewWidth / 2; viewWidth = viewWidth / 2; x = x - viewWidth / 2; y = y - viewWidth / 2; viewPoint.setLocation(x, y); setChanged(); notifyObservers(); } }
public Point2D.Double checkIntersectsSquare(Point2D.Double newLocation, RecCircle h) { double centreX, centreY, halfHeight, halfWidth, newX, newY; int thisDirection; Rectangle hitBounds = h.getRectangle().getHittableBounds(radius); Circle circle1 = h.getCircle1(); Circle circle2 = h.getCircle2(); newX = newLocation.getX(); newY = newLocation.getY(); centreX = hitBounds.getCenterX(); centreY = hitBounds.getCenterY(); halfHeight = hitBounds.getHeight() / 2; halfWidth = hitBounds.getWidth() / 2; if (hit(newX, newY, centreY, centreX, halfHeight, halfWidth)) { thisDirection = adjustThisDirection(); if (hitFromBelowOrAbove(x, centreX, y, centreY, halfHeight, halfWidth, thisDirection)) { if (thisDirection > 180) { if (circle2 != null) { newLocation = checkIntersectsCircle(newLocation, circle2); newX = newLocation.getX(); newY = newLocation.getY(); } else { breakComponent(h.getComponent()); perpendicularAngle = 270; newY = handleHitWall(centreY, halfHeight, perpendicularAngle); newX = adjustX(newY, thisDirection); newX = adjustBunnyWhenHit(perpendicularAngle, newX, newY).getX(); } } else { if (circle1 != null) { newLocation = checkIntersectsCircle(newLocation, circle1); newX = newLocation.getX(); newY = newLocation.getY(); } else { breakComponent(h.getComponent()); perpendicularAngle = 90; newY = handleHitWall(centreY, halfHeight, perpendicularAngle); newX = adjustX(newY, thisDirection); newX = adjustBunnyWhenHit(perpendicularAngle, newX, newY).getX(); } } } else { if ((thisDirection < 270) && (thisDirection > 90)) { perpendicularAngle = 180; } else { perpendicularAngle = 0; } breakComponent(h.getComponent()); newX = handleHitWall(centreX, halfWidth, perpendicularAngle); newY = adjustY(newX, sgn(179 - perpendicularAngle), thisDirection); newY = adjustBunnyWhenHit(perpendicularAngle, newX, newY).getY(); } orientation = fixOrientation(tempOrientation); } else { if (circle1 != null) { newLocation = checkIntersectsCircle(newLocation, circle1); newX = newLocation.getX(); newY = newLocation.getY(); } if (circle2 != null) { newLocation = checkIntersectsCircle(newLocation, circle2); newX = newLocation.getX(); newY = newLocation.getY(); } } newLocation.setLocation(newX, newY); return newLocation; }
public int geometryTest(Point2D worldCoord, int tolerance) { shapeList = model.getShapes(); if (selectedShape != null) { if (doHandleCheck(worldCoord, selectedShape)) { return selectedIndex; } } Point2D.Double objCoord = new Point2D.Double(); List<Shape> reversed = model.getShapesReversed(); for (int i = 0; i < reversed.size(); i++) { Shape s = reversed.get(i); AffineTransform worldToObj = new AffineTransform( Math.cos(s.getRotation()), -Math.sin(s.getRotation()), Math.sin(s.getRotation()), Math.cos(s.getRotation()), 0, 0); worldToObj.concatenate( new AffineTransform(1, 0, 0, 1, -s.getCenter().getX(), -s.getCenter().getY())); worldToObj.transform(worldCoord, objCoord); if (s instanceof Line) { Line l = (Line) s; Point2D.Double d = new Point2D.Double(); double x1 = l.getEnd().getX() - l.getCenter().getX(); double y1 = l.getEnd().getY() - l.getCenter().getY(); double lineLength = Math.sqrt((x1) * (x1) + (y1) * (y1)); d.setLocation((x1) / lineLength, (y1) / lineLength); double t = (objCoord.getX()) * d.getX() + (objCoord.getY()) * d.getY(); Point2D.Double q = new Point2D.Double(); q.setLocation(t * d.getX(), t * d.getY()); double qdist = Math.sqrt( (objCoord.getX() - q.getX()) * (objCoord.getX() - q.getX()) + (objCoord.getY() - q.getY()) * (objCoord.getY() - q.getY())); tolerance = (int) (tolerance * this.getScale()); if (qdist <= tolerance && t >= -tolerance && t <= lineLength + tolerance) { selectedShape = l; selectedIndex = shapeList.size() - i - 1; setChanged(); notifyObservers(); return selectedIndex; } } else if (s instanceof Square) { Square sq = (Square) s; if (Math.abs(objCoord.getX()) < sq.getSize() / 2 && Math.abs(objCoord.getY()) < sq.getSize() / 2) { selectedShape = sq; selectedIndex = shapeList.size() - i - 1; setChanged(); notifyObservers(); return selectedIndex; } } else if (s instanceof Rectangle) { Rectangle r = (Rectangle) s; if (Math.abs(objCoord.getX()) < r.getWidth() / 2 && Math.abs(objCoord.getY()) < r.getHeight() / 2) { selectedShape = r; selectedIndex = shapeList.size() - i - 1; setChanged(); notifyObservers(); return selectedIndex; } } else if (s instanceof Circle) { Circle c = (Circle) s; if (objCoord.getX() * objCoord.getX() + objCoord.getY() * objCoord.getY() < (c.getRadius() * c.getRadius())) { selectedShape = c; selectedIndex = shapeList.size() - i - 1; setChanged(); notifyObservers(); return selectedIndex; } } else if (s instanceof Ellipse) { Ellipse el = (Ellipse) s; double a = el.getWidth() / 2; double b = el.getHeight() / 2; if ((objCoord.getX() * objCoord.getX()) / (a * a) + (objCoord.getY() * objCoord.getY()) / (b * b) <= 1) { selectedShape = el; selectedIndex = shapeList.size() - i - 1; setChanged(); notifyObservers(); return selectedIndex; } } else if (s instanceof Triangle) { Triangle t = (Triangle) s; Point2D.Double a = new Point2D.Double( t.getA().getX() - t.getCenter().getX(), t.getA().getY() - t.getCenter().getY()); Point2D.Double b = new Point2D.Double( t.getB().getX() - t.getCenter().getX(), t.getB().getY() - t.getCenter().getY()); Point2D.Double c = new Point2D.Double( t.getC().getX() - t.getCenter().getX(), t.getC().getY() - t.getCenter().getY()); double triArea = calcArea(a, b, c); double a1 = calcArea(objCoord, b, c); double a2 = calcArea(objCoord, a, c); double a3 = calcArea(objCoord, a, b); if (a1 + a2 + a3 <= triArea) { selectedShape = t; selectedIndex = shapeList.size() - i - 1; setChanged(); notifyObservers(); return selectedIndex; } } else { selectedShape = null; selectedIndex = -1; setChanged(); notifyObservers(); } } selectedShape = null; selectedIndex = -1; setChanged(); notifyObservers(); return -1; }
@Override public void mousePressed(MouseEvent e) { AffineTransform viewToWorld = new AffineTransform(1, 0, 0, 1, viewPoint.getX(), viewPoint.getY()); AffineTransform scale = new AffineTransform(this.getScale(), 0, 0, this.getScale(), 0, 0); viewToWorld.concatenate(scale); p1 = new Point2D.Double(e.getPoint().getX(), e.getPoint().getY()); viewToWorld.transform(p1, p1); if (button == "line") { currentShape = new Line(col, p1, p1); } else if (button == "square") { currentShape = new Square(col, p1, 0); } else if (button == "rectangle") { currentShape = new Rectangle(col, p1, 0, 0); } else if (button == "circle") { currentShape = new Circle(col, p1, 0); } else if (button == "ellipse") { currentShape = new Ellipse(col, p1, 0, 0); } else if (button == "triangle") { if (triangleCount == 0) { t1 = new Point2D.Double(p1.getX(), p1.getY()); triangleCount++; } else if (triangleCount == 1) { t2 = new Point2D.Double(p1.getX(), p1.getY()); triangleCount++; } else { t3 = new Point2D.Double(p1.getX(), p1.getY()); Point2D.Double center = new Point2D.Double(); center.setLocation( (t1.getX() + t2.getX() + t3.getX()) / 3, (t1.getY() + t2.getY() + t3.getY()) / 3); triangleCount = 0; Shape t = new Triangle(col, center, t1, t2, t3); model.addShape(t); } return; } else if (button == "select") { selectedIndex = geometryTest(p1, 4); if (selectedIndex > -1) { Shape s = model.getShape(selectedIndex); GUIFunctions.changeSelectedColor(s.getColor()); diff = new Point2D.Double(p1.getX() - s.getCenter().getX(), p1.getY() - s.getCenter().getY()); if (doHandleCheck(p1, selectedShape)) { handleSelected = true; if (s instanceof Line) { Line l = (Line) s; Point2D.Double len = new Point2D.Double( l.getEnd().getX() - l.getCenter().getX(), l.getEnd().getY() - l.getCenter().getY()); AffineTransform worldToObj = new AffineTransform(1, 0, 0, 1, -s.getCenter().getX(), -s.getCenter().getY()); Point2D.Double objCoord = new Point2D.Double(); worldToObj.transform(p1, objCoord); if (objCoord.getX() * objCoord.getX() + objCoord.getY() * objCoord.getY() < 100 * this.getScale()) { lineHandleSelected = 1; } else if ((objCoord.getX() - len.getX()) * (objCoord.getX() - len.getX()) + (objCoord.getY() - len.getY()) * (objCoord.getY() - len.getY()) < 100 * this.getScale()) { lineHandleSelected = 2; } } } } return; } else { return; } model.addShape(currentShape); }
@Override public void mouseDragged(MouseEvent e) { AffineTransform viewToWorld = new AffineTransform(1, 0, 0, 1, viewPoint.getX(), viewPoint.getY()); AffineTransform scale = new AffineTransform(this.getScale(), 0, 0, this.getScale(), 0, 0); viewToWorld.concatenate(scale); p2 = new Point2D.Double(e.getPoint().getX(), e.getPoint().getY()); viewToWorld.transform(p2, p2); if (button == "line") { currentShape = model.getShape(model.getSize() - 1); Line l = (Line) currentShape; l.setEnd(p2); model.deleteShape(model.getSize() - 1); model.addShape(l); } else if (button == "square") { double size = Math.min((Math.abs(p1.getX() - p2.getX())), (Math.abs(p1.getY() - p2.getY()))); Point2D.Double upLeft = new Point2D.Double(); if (p1.getX() <= p2.getX() && p1.getY() <= p2.getY()) { upLeft.setLocation(p1.getX(), p1.getY()); } else if (p1.getX() <= p2.getX() && p1.getY() > p2.getY()) { upLeft.setLocation(p1.getX(), p1.getY() - size); } else if (p1.getX() > p2.getX() && p1.getY() <= p2.getY()) { upLeft.setLocation(p1.getX() - size, p1.getY()); } else { upLeft.setLocation(p1.getX() - size, p1.getY() - size); } Point2D.Double center = new Point2D.Double(upLeft.getX() + size / 2, upLeft.getY() + size / 2); currentShape = model.getShape(model.getSize() - 1); Square s = (Square) currentShape; s.setCenter(center); s.setSize(size); model.deleteShape(model.getSize() - 1); model.addShape(s); } else if (button == "rectangle") { Point2D.Double upLeft = new Point2D.Double(); upLeft.setLocation(Math.min(p1.getX(), p2.getX()), Math.min(p1.getY(), p2.getY())); Double width = Math.abs(p1.getX() - p2.getX()); Double height = Math.abs(p1.getY() - p2.getY()); currentShape = model.getShape(model.getSize() - 1); Rectangle r = (Rectangle) currentShape; Point2D.Double center = new Point2D.Double(upLeft.getX() + width / 2, upLeft.getY() + height / 2); r.setHeight(height); r.setWidth(width); r.setCenter(center); model.deleteShape(model.getSize() - 1); model.addShape(r); } else if (button == "circle") { double size = Math.min((Math.abs(p1.getX() - p2.getX())), (Math.abs(p1.getY() - p2.getY()))); double radius = size / 2; Point2D.Double upLeft = new Point2D.Double(); if (p1.getX() <= p2.getX() && p1.getY() <= p2.getY()) { upLeft.setLocation(p1.getX(), p1.getY()); } else if (p1.getX() <= p2.getX() && p1.getY() > p2.getY()) { upLeft.setLocation(p1.getX(), p1.getY() - size); } else if (p1.getX() > p2.getX() && p1.getY() <= p2.getY()) { upLeft.setLocation(p1.getX() - size, p1.getY()); } else { upLeft.setLocation(p1.getX() - size, p1.getY() - size); } Point2D.Double center = new Point2D.Double(upLeft.getX() + radius, upLeft.getY() + radius); currentShape = model.getShape(model.getSize() - 1); Circle c = (Circle) currentShape; c.setCenter(center); c.setRadius(radius); model.deleteShape(model.getSize() - 1); model.addShape(c); } else if (button == "ellipse") { Point2D.Double center = new Point2D.Double((p1.getX() + p2.getX()) / 2, (p1.getY() + p2.getY()) / 2); Double width = Math.abs(p1.getX() - p2.getX()); Double height = Math.abs(p1.getY() - p2.getY()); currentShape = model.getShape(model.getSize() - 1); Ellipse el = (Ellipse) currentShape; el.setCenter(center); el.setHeight(height); el.setWidth(width); model.deleteShape(model.getSize() - 1); model.addShape(el); } else if (button == "select" && selectedIndex > -1) { if (handleSelected) { AffineTransform worldToObj = new AffineTransform( 1, 0, 0, 1, -selectedShape.getCenter().getX(), -selectedShape.getCenter().getY()); Point2D.Double objCoord = new Point2D.Double(); worldToObj.transform(p2, objCoord); if (selectedShape instanceof Line) { Line l = (Line) selectedShape; if (lineHandleSelected == 1) { Point2D.Double newCenter = new Point2D.Double(p2.getX(), p2.getY()); l.setCenter(newCenter); } else if (lineHandleSelected == 2) { Point2D.Double newEnd = new Point2D.Double(p2.getX(), p2.getY()); l.setEnd(newEnd); } selectedShape = l; model.setShape(selectedIndex, selectedShape); } else { double theta = Math.acos( -objCoord.getY() / Math.sqrt(Math.pow(objCoord.getX(), 2) + Math.pow(-objCoord.getY(), 2))); if (objCoord.getX() < 0) { theta = -theta; } selectedShape.setRotation(theta); model.setShape(selectedIndex, selectedShape); } } else { Point2D.Double newCenter = new Point2D.Double((p2.getX() - diff.getX()), (p2.getY() - diff.getY())); if (selectedShape instanceof Line) { Line l = (Line) selectedShape; Point2D.Double len = new Point2D.Double( l.getEnd().getX() - l.getCenter().getX(), l.getEnd().getY() - l.getCenter().getY()); Point2D.Double newEnd = new Point2D.Double((newCenter.getX() + len.getX()), (newCenter.getY() + len.getY())); l.setEnd(newEnd); selectedShape = l; } else if (selectedShape instanceof Triangle) { Triangle t = (Triangle) selectedShape; Point2D.Double change = new Point2D.Double( newCenter.getX() - selectedShape.getCenter().getX(), newCenter.getY() - selectedShape.getCenter().getY()); t.setA( new Point2D.Double(t.getA().getX() + change.getX(), t.getA().getY() + change.getY())); t.setB( new Point2D.Double(t.getB().getX() + change.getX(), t.getB().getY() + change.getY())); t.setC( new Point2D.Double(t.getC().getX() + change.getX(), t.getC().getY() + change.getY())); selectedShape = t; } selectedShape.setCenter(newCenter); model.setShape(selectedIndex, selectedShape); } } }
/** * Sets the center point * * @param x the x-coordinate of the center * @param y the y-coordinate of the center */ public void setCenterPoint(double x, double y) { center.setLocation(x, y); }
public double getTerminalAttachPoint( double terminalPositionAngle, Rectangle2D.Double globalBounds, AffineTransform localToGlobalTx, Point2D.Double arcAttachPoint) { double nw = globalBounds.getWidth(); // node width double nh = globalBounds.getHeight(); // node height double nhalfw = nw / 2.0; // half node width double nhalfh = nh / 2.0; // half node height double tanTheta = Math.tan(terminalPositionAngle); /* * Idea: A node has four sides. Firstly, see which side intersects a line with * an angle of "theta", originating at the centre of the node. * Secondly, see where exactly on the side this intersection happens. */ // angle in radians between horizontal line through centre of node and top left corner double alpha = Math.atan2(nh, nw); double beta = DisplayConstants.HALF_PI - alpha; // in radians double x = 0.0; double y = 0.0; double tmpAngle = alpha + 2 * beta; if (terminalPositionAngle >= alpha && terminalPositionAngle <= tmpAngle) { // intersects with bottom side of node y = nhalfh; x = y / tanTheta; } else if ((terminalPositionAngle >= tmpAngle) || (terminalPositionAngle <= -DisplayConstants.HALF_PI)) { // intersects with left side of node double x1 = 0; // (x1,y1) is the top point of the triangle double y1 = -nhalfh; double x2 = -nhalfw; // (x2,y2) is the bottom left point) double y2 = nhalfh; double x3 = 0; // (x3,y3) is the center point double y3 = 0; double x4 = -nhalfw; // (x4,y4) is the left edge of the box at a y position relative to the angle double y4 = x4 * tanTheta; double u1 = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); x = x1 + u1 * (x2 - x1); y = y1 + u1 * (y2 - y1); } else { // intersects with right side of node double x1 = 0; // (x1,y1) is the top of triangle double y1 = -nhalfh; double x2 = nhalfw; // (x2,y2) is the bottom right corner double y2 = nhalfh; double x3 = 0; // (x3,y3) is the center of triangle double y3 = 0; double x4 = nhalfw; // (x4,y4) is the right edge relative of the box to the angle double y4 = x4 * tanTheta; double u1 = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); x = x1 + u1 * (x2 - x1); y = y1 + u1 * (y2 - y1); } arcAttachPoint.setLocation(x, y); return terminalPositionAngle; }