Wire.java

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