import java.awt.*; import java.awt.geom.*; import java.util.ArrayList; import java.util.Collections; public class Wire implements Comparable<Wire> { ArrayList<Point2D> pts = new ArrayList<Point2D>(); Color color = Color.BLACK; boolean stub = false; Wire wstub = null; Rectangle2D bounds; int ndx; // wire number int node = -1; public Wire() { }; public Wire(String[] tokens) { int len = tokens.length; int n = (len-1)/2; for (int k=1; k<1+2*n; k+=2) { double x = Double.parseDouble(tokens[k]); double y = Double.parseDouble(tokens[k+1]); Point2D.Double p = new Point2D.Double(x,y); pts.add(p); } if (tokens.length>2*n+1) stub = true; set_limits(); } public void add(double x, double y) { Point2D.Double p = new Point2D.Double(x,y); pts.add(p); set_limits(); } public String toString() { String s = "W"; for (Point2D p: pts) { s += " " + p.getX() + " " + p.getY(); } if (stub) s += " *"; return s; } public void draw(Graphics g) { Graphics2D g2 = (Graphics2D) g; Stroke saveStroke = g2.getStroke(); g2.setStroke(new BasicStroke(0.025f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND)); Paint savePaint = g2.getPaint(); g2.setPaint(color); GeneralPath path = new GeneralPath(); boolean start = true; double x=0.0, y=0.0; for (Point2D p: pts) { x = p.getX(); y = -p.getY(); if (start) path.moveTo(x,y); else path.lineTo(x,y); start = false; } g2.draw(path); if (stub) { Ellipse2D circ = new Ellipse2D.Double(x-0.04,y-0.04,0.08,0.08); g2.fill(circ); } g2.setPaint(Color.BLUE); //g2.draw(bounds); g2.setStroke(saveStroke); g2.setPaint(savePaint); } // limits define a bounding box around the wire public void set_limits() { Point2D pt = pts.get(0); double xmin, xmax, ymin, ymax; xmin = xmax = pt.getX(); ymin = ymax = -pt.getY(); for (Point2D p: pts) { double v = p.getX(); if (v<xmin) xmin = v; if (v>xmax) xmax = v; v = -p.getY(); if (v<ymin) ymin = v; if (v>ymax) ymax = v; } xmin += -0.05; xmax += 0.05; ymin += -0.05; ymax += 0.05; bounds = new Rectangle2D.Double(xmin,ymin,xmax-xmin,ymax-ymin); } // returns true if point is outside the bounding rectangle public boolean contains(Point2D p) { return bounds.contains(p.getX(),-p.getY()); /* double v = p.getX(); if (v>xmax) return true; if (v<xmin) return true; v = p.getY(); if (v>ymax) return true; if (v<ymin) return true; return false; */ } // returns point of intersection if p intersects wire public Point2D intersects(Point2D p) { if (!contains(p)) return null; Point2D p1 = pts.get(0); // if p is near a bounding point, return that point if (p1.distance(p)<0.05) return p1; Point2D p2, pv; for (int n=1; n<pts.size(); n++) { p2 = pts.get(n); if (p2.distance(p)<0.05) return p2; Line2D v = new Line2D.Double(p1,p2); // see if p is close to intersecting the line from p1 to p2 pv = intersects(v,p); if (pv!=null) return pv; p1 = p2; } return null; } // finds intersection if p intersects line segment v public Point2D intersects(Line2D v, Point2D p) { double dist, q; double x1 = v.getX1(); double x2 = v.getX2(); double y1 = v.getY1(); double y2 = v.getY2(); double kx = x2-x1; double ky = y2-y1; double px = p.getX(); double py = p.getY(); double ksq = kx*kx+ky*ky; q = (px-x1)*kx + (py-y1)*ky; q = q/ksq; Point2D pv = new Point2D.Double(x1+q*kx,y1+q*ky); dist = pv.distance(p); if (dist>0.05) return null; if (q<0.0 || q>1.0) return null; return pv; } public int compareStub(Wire w) { if (stub==w.stub) return 0; if (stub & !w.stub) return 1; return -1; } public int compareTo(Wire w) { // ground nodes at bottom of list if (node==0) { if (w.node==0) return compareStub(w); else return 1; } if (w.node==0) return -1; if (node<w.node) return -1; if (node>w.node) return 1; return compareStub(w); } public static Wire make(int node, boolean stub) { Wire w = new Wire(); w.node = node; w.stub = stub; return w; } public static void test1() { ArrayList<Wire> wlist = new ArrayList<>(); wlist.add(make(0,true)); wlist.add(make(0,false)); wlist.add(make(2,true)); wlist.add(make(2,false)); wlist.add(make(1,false)); wlist.add(make(1,true)); Collections.sort(wlist); for (Wire w: wlist) System.out.println(w.node + " "+w.stub); } static public void main(String[] args) { String [] tokens = { "W", "1.2", "1.2","1.9","1.2"}; Wire w = new Wire(tokens); System.out.println(w); Wire.test1(); } }
Maintained by John Loomis, updated Sun Mar 08 13:01:03 2020