import java.awt.geom.Path2D; import java.awt.geom.AffineTransform; import java.awt.Graphics2D; import java.awt.geom.Line2D; import java.awt.*; public class GSpring extends Spring implements Draggable { private static final double xPoints[]={0,0.10, 0.125, 0.175, 0.225, 0.275, 0.325, 0.375, 0.425, 0.475, 0.525,0.575,0.625, 0.675,0.725,0.775,0.825,0.875, 0.90,1.0}; private static final double yPoints[]={0,0,-0.1,0.1,-0.1,0.1,-0.1,0.1,-0.1,0.1, -0.1,0.1,-0.1,0.1,-0.1,0.1,-0.1,0.1,0,0}; private static final Path2D.Double polyline = new Path2D.Double(Path2D.WIND_EVEN_ODD,xPoints.length); private Path2D.Double shape; private Color color = Color.BLACK; private Vector2D graphicsPosA =null; // to draw a spring we need private Vector2D graphicsPosB =null; // extremes well definied // when it is not connected static { // static initialization block polyline.moveTo (xPoints[0], yPoints[0]); for (int index = 1; index < xPoints.length;index++) polyline.lineTo(xPoints[index], yPoints[index]); } public GSpring(float restLength, float stiffness) { super(restLength, stiffness); graphicsPosA = new Vector2D(0,restLength); graphicsPosB = new Vector2D(restLength,restLength); AffineTransform at = AffineTransform.getTranslateInstance(0,0); Vector2D v = getVector(); at.rotate(v.getX(), v.getY()); at.scale(v.module(), 2*restLength-v.module()); shape = (Path2D.Double) at.createTransformedShape(polyline); } public void draw (Graphics2D g){ Vector2D a=getPositionA(); double ax = a.getX(); double ay = a.getY(); Vector2D v = getVector(); AffineTransform at = AffineTransform.getTranslateInstance(ax, ay); at.rotate(v.getX(), v.getY()); at.scale(v.module(), 2*restLength-v.module()); shape = (Path2D.Double) at.createTransformedShape(polyline); g.setColor(color); g.draw(shape); } public boolean contains(double x, double y){ return shape.contains(x,y); } public void drag(double x, double y){ Vector2D a=getPositionA(); Vector2D b=getPositionB(); double da = Math.abs(a.getX()-x)+Math.abs(a.getY()-y); // distance to a double db = Math.abs(b.getX()-x)+Math.abs(b.getY()-y); // distance to a if (da < db) { detachBlock_a(); graphicsPosA.moveTo(x,y); } else { detachBlock_b(); graphicsPosB.moveTo(x,y); } } public Vector2D getPositionA() { Vector2D p = super.getPositionA(); if (p != null) return p; else return graphicsPosA; } public Vector2D getPositionB() { Vector2D p = super.getPositionB(); if (p != null) return p; else return graphicsPosB; } public void updateState(){ if (block_a==null && block_b==null) return; if (block_a!=null) { Vector2D v = getVector().unitary().times(restLength); graphicsPosB = getPositionA().plus(v); return; } if (block_b!=null) { Vector2D v = getVector().unitary().times(restLength); graphicsPosA = getPositionB().minus(v); return; } } public void attachNearElement(double x, double y, BlockSpringConfiguration bsc){ Vector2D a=getPositionA(); if ((a.getX()==x) && (a.getY()==y)) { GBlock block = bsc.findBlock(x,y); if (block!=null) attachBlock_a(block); else return; } Vector2D b=getPositionB(); if ((b.getX()==x) && (b.getY()==y)) { GBlock block = bsc.findBlock(x,y); if (block!=null) attachBlock_b(block); return; } } public void setSelectedColor() { color = Color.RED; } public void setDefaultColor() { color = Color.BLACK; } }