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