use of com.cburch.logisim.data.Direction in project logisim-evolution by reds-heig.
the class Connector method findShortestPath.
private static SearchNode findShortestPath(List<SearchNode> nodes, Set<Location> pathLocs, AvoidanceMap avoid) {
PriorityQueue<SearchNode> q = new PriorityQueue<SearchNode>(nodes);
HashSet<SearchNode> visited = new HashSet<SearchNode>();
int iters = 0;
while (!q.isEmpty() && iters < MAX_SEARCH_ITERATIONS) {
iters++;
SearchNode n = q.remove();
if (iters % 64 == 0 && ConnectorThread.isOverrideRequested() || n == null) {
return null;
}
if (n.isDestination()) {
return n;
}
boolean added = visited.add(n);
if (!added) {
continue;
}
Location loc = n.getLocation();
Direction dir = n.getDirection();
int neighbors = 3;
Object allowed = avoid.get(loc);
if (allowed != null && n.isStart() && pathLocs.contains(loc)) {
allowed = null;
}
if (allowed == ALLOW_NEITHER) {
neighbors = 0;
} else if (allowed == ALLOW_VERTICAL) {
if (dir == null) {
dir = Direction.NORTH;
neighbors = 2;
} else if (dir == Direction.NORTH || dir == Direction.SOUTH) {
neighbors = 1;
} else {
neighbors = 0;
}
} else if (allowed == ALLOW_HORIZONTAL) {
if (dir == null) {
dir = Direction.EAST;
neighbors = 2;
} else if (dir == Direction.EAST || dir == Direction.WEST) {
neighbors = 1;
} else {
neighbors = 0;
}
} else {
if (dir == null) {
dir = Direction.NORTH;
neighbors = 4;
} else {
neighbors = 3;
}
}
for (int i = 0; i < neighbors; i++) {
Direction oDir;
switch(i) {
case 0:
oDir = dir;
break;
case 1:
oDir = neighbors == 2 ? dir.reverse() : dir.getLeft();
break;
case 2:
oDir = dir.getRight();
break;
default:
// must be 3
oDir = dir.reverse();
}
SearchNode o = n.next(oDir, allowed != null);
if (o != null && !visited.contains(o)) {
q.add(o);
}
}
}
return null;
}
use of com.cburch.logisim.data.Direction in project logisim-evolution by reds-heig.
the class Connector method processConnection.
private static void processConnection(ConnectionData conn, int dx, int dy, HashSet<Location> connLocs, ArrayList<SearchNode> connNodes, AvoidanceMap selAvoid) {
Location cur = conn.getLocation();
Location dest = cur.translate(dx, dy);
if (selAvoid.get(cur) == null) {
Direction preferred = conn.getDirection();
if (preferred == null) {
if (Math.abs(dx) > Math.abs(dy)) {
preferred = dx > 0 ? Direction.EAST : Direction.WEST;
} else {
preferred = dy > 0 ? Direction.SOUTH : Direction.NORTH;
}
}
connLocs.add(cur);
connNodes.add(new SearchNode(conn, cur, preferred, dest));
}
for (Wire w : conn.getWirePath()) {
for (Location loc : w) {
if (selAvoid.get(loc) == null || loc.equals(dest)) {
boolean added = connLocs.add(loc);
if (added) {
Direction dir = null;
if (w.endsAt(loc)) {
if (w.isVertical()) {
int y0 = loc.getY();
int y1 = w.getOtherEnd(loc).getY();
dir = y0 < y1 ? Direction.NORTH : Direction.SOUTH;
} else {
int x0 = loc.getX();
int x1 = w.getOtherEnd(loc).getX();
dir = x0 < x1 ? Direction.WEST : Direction.EAST;
}
}
connNodes.add(new SearchNode(conn, loc, dir, dest));
}
}
}
}
}
use of com.cburch.logisim.data.Direction in project logisim-evolution by reds-heig.
the class SearchNode method next.
public SearchNode next(Direction moveDir, boolean crossing) {
int newDist = dist;
Direction connDir = conn.getDirection();
Location nextLoc = loc.translate(moveDir, 10);
boolean exWire = extendsWire && moveDir == connDir;
if (exWire) {
newDist += 9;
} else {
newDist += 10;
}
if (crossing)
newDist += CROSSING_PENALTY;
if (moveDir != dir)
newDist += TURN_PENALTY;
if (nextLoc.getX() < 0 || nextLoc.getY() < 0) {
return null;
} else {
return new SearchNode(nextLoc, moveDir, conn, dest, newDist, exWire, this);
}
}
use of com.cburch.logisim.data.Direction in project logisim-evolution by reds-heig.
the class SearchNode method getHeuristic.
private int getHeuristic() {
Location cur = loc;
Location dst = dest;
Direction curDir = dir;
int dx = dst.getX() - cur.getX();
int dy = dst.getY() - cur.getY();
int ret = -1;
if (extendsWire) {
ret = -1;
if (curDir == Direction.EAST) {
if (dx > 0)
ret = dx / 10 * 9 + Math.abs(dy);
} else if (curDir == Direction.WEST) {
if (dx < 0)
ret = -dx / 10 * 9 + Math.abs(dy);
} else if (curDir == Direction.SOUTH) {
if (dy > 0)
ret = Math.abs(dx) + dy / 10 * 9;
} else if (curDir == Direction.NORTH) {
if (dy < 0)
ret = Math.abs(dx) - dy / 10 * 9;
}
}
if (ret < 0) {
ret = Math.abs(dx) + Math.abs(dy);
}
boolean penalizeDoubleTurn = false;
if (curDir == Direction.EAST) {
penalizeDoubleTurn = dx < 0;
} else if (curDir == Direction.WEST) {
penalizeDoubleTurn = dx > 0;
} else if (curDir == Direction.NORTH) {
penalizeDoubleTurn = dy > 0;
} else if (curDir == Direction.SOUTH) {
penalizeDoubleTurn = dy < 0;
} else if (curDir == null) {
if (dx != 0 || dy != 0)
ret += TURN_PENALTY;
}
if (penalizeDoubleTurn) {
ret += 2 * TURN_PENALTY;
} else if (dx != 0 && dy != 0) {
ret += TURN_PENALTY;
}
return ret;
}
use of com.cburch.logisim.data.Direction in project logisim-evolution by reds-heig.
the class SubcircuitFactory method drawPinsName.
private void drawPinsName(InstancePainter painter, Bounds bds, Direction facing, Direction defaultFacing) {
Map<Direction, List<Instance>> edge;
Collection<Instance> pins = source.getAppearance().GetCircuitPin().getPins();
edge = new HashMap<Direction, List<Instance>>();
edge.put(Direction.EAST, new ArrayList<Instance>());
edge.put(Direction.WEST, new ArrayList<Instance>());
int MaxLeftLabelLength = 0;
int MaxRightLabelLength = 0;
double angle;
for (Instance pin : pins) {
Direction pinEdge;
Text label = new Text(0, 0, pin.getAttributeValue(StdAttr.LABEL));
int LabelWidth = label.getText().length() * DrawAttr.FixedFontCharWidth;
if (pin.getAttributeValue(Pin.ATTR_TYPE)) {
pinEdge = Direction.EAST;
if (LabelWidth > MaxRightLabelLength)
MaxRightLabelLength = LabelWidth;
} else {
pinEdge = Direction.WEST;
if (LabelWidth > MaxLeftLabelLength)
MaxLeftLabelLength = LabelWidth;
}
List<Instance> e = edge.get(pinEdge);
e.add(pin);
}
for (Map.Entry<Direction, List<Instance>> entry : edge.entrySet()) {
source.getAppearance().sortPinsList(entry.getValue(), entry.getKey());
}
/* Here we manage to have always the beginning of the pin label
* close to the pin and avoid the label being upside down.
*/
angle = facing.toRadians();
angle = Math.toRadians(-Math.toDegrees(angle) % Math.toDegrees(Math.PI));
placePins(painter, edge, bds.getX(), bds.getY(), bds.getWidth(), bds.getHeight(), angle, facing);
}
Aggregations