use of com.cburch.logisim.analyze.model.Implicant in project logisim-evolution by reds-heig.
the class KarnaughMapPanel method paintImplicant.
private void paintImplicant(Graphics g, Implicant imp, int x, int y, int rows, int cols) {
int rowMax = -1;
int rowMin = rows;
int colMax = -1;
int colMin = cols;
boolean oneRowFound = false;
int count = 0;
for (Implicant sq : imp.getTerms()) {
int tableRow = sq.getRow();
int row = getRow(tableRow, rows, cols);
int col = getCol(tableRow, rows, cols);
if (row == 1)
oneRowFound = true;
if (row > rowMax)
rowMax = row;
if (row < rowMin)
rowMin = row;
if (col > colMax)
colMax = col;
if (col < colMin)
colMin = col;
++count;
}
int numCols = colMax - colMin + 1;
int numRows = rowMax - rowMin + 1;
int covered = numCols * numRows;
int d = 2 * IMP_RADIUS;
if (covered == count) {
g.fillRoundRect(x + colMin * cellWidth + IMP_INSET, y + rowMin * cellHeight + IMP_INSET, numCols * cellWidth - 2 * IMP_INSET, numRows * cellHeight - 2 * IMP_INSET, d, d);
/*easy case*/
} else if (numCols > 4) {
/* TODO: Make the group marking more clear */
for (Implicant sq : imp.getTerms()) {
int tableRow = sq.getRow();
int row = getRow(tableRow, rows, cols);
int col = getCol(tableRow, rows, cols);
int w = cellWidth - 3;
int h = cellHeight - 3;
g.fillRect(2 + x + col * cellWidth, 2 + y + row * cellHeight, w, h);
}
} else if (covered == 16) {
if (count == 4) {
int w = cellWidth - IMP_INSET;
int h = cellHeight - IMP_INSET;
int x1 = x + 3 * cellWidth + IMP_INSET;
int y1 = y + 3 * cellHeight + IMP_INSET;
g.fillRoundRect(x + colMin * cellWidth, y, w, h, d, d);
g.fillRoundRect(x1 + colMin * cellWidth, y, w, h, d, d);
g.fillRoundRect(x + colMin * cellWidth, y1, w, h, d, d);
g.fillRoundRect(x1 + colMin * cellWidth, y1, w, h, d, d);
} else if (oneRowFound) {
// first and last columns
int w = cellWidth - IMP_INSET;
int h = 4 * cellHeight - 2 * IMP_INSET;
int x1 = x + 3 * cellWidth + IMP_INSET;
g.fillRoundRect(x + colMin * cellWidth, y + IMP_INSET, w, h, d, d);
g.fillRoundRect(x1 + colMin * cellWidth, y + IMP_INSET, w, h, d, d);
} else {
// first and last rows
int w = 4 * cellWidth - 2 * IMP_INSET;
int h = cellHeight - IMP_INSET;
int y1 = y + 3 * cellHeight + IMP_INSET;
g.fillRoundRect(x + colMin * cellWidth + IMP_INSET, y, w, h, d, d);
g.fillRoundRect(x + colMin * cellWidth + IMP_INSET, y1, w, h, d, d);
}
} else if (numCols == 4) {
int top = y + rowMin * cellHeight + IMP_INSET;
int w = cellWidth - IMP_INSET;
int h = numRows * cellHeight - 2 * IMP_INSET;
// handle half going off left edge
g.fillRoundRect(x + colMin * cellWidth, top, w, h, d, d);
// handle half going off right edge
g.fillRoundRect(x + 3 * cellWidth + colMin * cellWidth + IMP_INSET, top, w, h, d, d);
/*
* This is the proper way, with no rounded rectangles along the
* table's edge; but I found that the different regions were liable
* to overlap, particularly the arcs with the rectangles. (Plus, I
* was too lazy to figure this out for the 16 case.) int y0 = y +
* rowMin * cellHeight + IMP_INSET; int y1 = y + rowMax * cellHeight
* + cellHeight - IMP_INSET; int dy = y1 - y0; int x0 = x +
* cellWidth - IMP_INSET; int x1 = x + 3 * cellWidth + IMP_INSET;
*
* // half going off left edge g.fillRect(x, y0, cellWidth -
* IMP_INSET - IMP_RADIUS, dy); g.fillRect(x0 - IMP_RADIUS, y0 +
* IMP_RADIUS, IMP_RADIUS, dy - d); g.fillArc(x0 - d, y0, d, d, 0,
* 90); g.fillArc(x0 - d, y1 - d, d, d, 0, -90);
*
* // half going off right edge g.fillRect(x1 + IMP_RADIUS, y0,
* cellWidth - IMP_INSET - IMP_RADIUS, dy); g.fillRect(x1, y0 +
* IMP_RADIUS, IMP_RADIUS, dy - d); g.fillArc(x1, y0, d, d, 180,
* 90); g.fillArc(x1, y1 - d, d, d, 180, -90);
*/
} else {
// numRows == 4
int left = x + colMin * cellWidth + IMP_INSET;
int w = numCols * cellWidth - 2 * IMP_INSET;
int h = cellHeight - IMP_INSET;
// handle half going off top edge
g.fillRoundRect(left, y, w, h, d, d);
// handle half going off right edge
g.fillRoundRect(left, y + 3 * cellHeight + IMP_INSET, w, h, d, d);
}
}
use of com.cburch.logisim.analyze.model.Implicant in project logisim-evolution by reds-heig.
the class KarnaughMapPanel method paintComponent.
@Override
public void paintComponent(Graphics g) {
/* Anti-aliasing changes from https://github.com/hausen/logisim-evolution */
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g);
TruthTable table = model.getTruthTable();
int inputCount = table.getInputColumnCount();
Dimension sz = getSize();
String message = null;
if (output == null) {
message = Strings.get("karnaughNoOutputError");
} else if (inputCount > MAX_VARS) {
message = Strings.get("karnaughTooManyInputsError");
}
if (message != null) {
g.setFont(HeaderFont);
GraphicsUtil.drawCenteredText(g, message, sz.width / 2, sz.height / 2);
return;
}
int left = computeMargin(sz.width, tableWidth);
int top = computeMargin(sz.height, tableHeight);
int x = left;
int y = top;
int rowVars = ROW_VARS[inputCount];
int colVars = COL_VARS[inputCount];
int rows = 1 << rowVars;
int cols = 1 << colVars;
g.setFont(HeaderFont);
FontMetrics headFm = g.getFontMetrics(HeaderFont);
for (int i = 0; i < inputCount; i++) {
String header = model.getInputs().get(i);
Boolean rotated = false;
int middleOffset = (headFm.stringWidth(header) >> 1);
int xoffset = headHeight + 11;
int yoffset = headHeight + 11;
switch(i) {
case 0:
if (inputCount == 1) {
rotated = false;
xoffset += cellWidth + cellWidth / 2;
yoffset = headFm.getAscent();
} else {
rotated = true;
yoffset += (rows - 1) * cellHeight;
if (inputCount < 4)
yoffset += cellHeight / 2;
xoffset = headFm.getAscent();
}
break;
case 1:
if (inputCount == 2) {
rotated = false;
xoffset += cellWidth + cellWidth / 2;
yoffset = headFm.getAscent();
} else if (inputCount == 3) {
rotated = false;
xoffset += 3 * cellWidth;
yoffset = headFm.getAscent();
} else {
rotated = true;
xoffset += 4 * cellWidth + 11 + headFm.getAscent();
yoffset += 2 * cellHeight;
if (inputCount > 4) {
xoffset += 4 * cellWidth;
}
}
break;
case 2:
rotated = false;
if (inputCount == 3) {
xoffset += 2 * cellWidth;
yoffset += 11 + 2 * cellHeight + headFm.getAscent();
} else if (inputCount == 4) {
xoffset += 3 * cellWidth;
yoffset = headFm.getAscent();
} else {
xoffset += 6 * cellWidth;
yoffset += 11 + 4 * cellHeight + headFm.getAscent();
}
break;
case 3:
rotated = false;
if (inputCount == 4) {
xoffset += 2 * cellWidth;
yoffset += 11 + 4 * cellHeight + headFm.getAscent();
} else {
xoffset += 4 * cellWidth;
yoffset = headFm.getAscent();
}
break;
case 4:
rotated = false;
xoffset += 2 * cellWidth;
yoffset += 11 + 4 * cellHeight + headFm.getAscent() + headHeight;
break;
default:
break;
}
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D) g.create();
if (rotated) {
g2.translate(xoffset + x, yoffset + y);
g2.rotate(-Math.PI / 2.0);
g2.drawString(header, -middleOffset, 0);
} else
g2.drawString(header, xoffset + x - middleOffset, yoffset + y);
if (i == 4)
g2.drawString(header, 4 * cellWidth + xoffset + x - middleOffset, yoffset + y);
}
}
x += headHeight;
y += headHeight;
g.setFont(EntryFont);
FontMetrics fm = g.getFontMetrics();
int dy = (cellHeight + fm.getAscent()) / 2;
x += 11;
y += 11;
/* Here the 0/1 labels are placed */
switch(cols) {
case 2:
g.drawLine(x + cellWidth, y - 8, x + 2 * cellWidth, y - 8);
g.drawLine(x + cellWidth, y - 9, x + 2 * cellWidth, y - 9);
break;
case 4:
g.drawLine(x + 2 * cellWidth, y - 8, x + 4 * cellWidth, y - 8);
g.drawLine(x + 2 * cellWidth, y - 9, x + 4 * cellWidth, y - 9);
g.drawLine(x + cellWidth, y + 8 + rows * cellHeight, x + 3 * cellWidth, y + 8 + rows * cellHeight);
g.drawLine(x + cellWidth, y + 9 + rows * cellHeight, x + 3 * cellWidth, y + 9 + rows * cellHeight);
break;
case 8:
g.drawLine(x + cellWidth, y + 8 + rows * cellHeight + headHeight, x + 3 * cellWidth, y + 8 + rows * cellHeight + headHeight);
g.drawLine(x + cellWidth, y + 9 + rows * cellHeight + headHeight, x + 3 * cellWidth, y + 9 + rows * cellHeight + headHeight);
g.drawLine(x + 5 * cellWidth, y + 8 + rows * cellHeight + headHeight, x + 7 * cellWidth, y + 8 + rows * cellHeight + headHeight);
g.drawLine(x + 5 * cellWidth, y + 9 + rows * cellHeight + headHeight, x + 7 * cellWidth, y + 9 + rows * cellHeight + headHeight);
g.drawLine(x + 2 * cellWidth, y - 8, x + 6 * cellWidth, y - 8);
g.drawLine(x + 2 * cellWidth, y - 9, x + 6 * cellWidth, y - 9);
g.drawLine(x + 4 * cellWidth, y + 8 + rows * cellHeight, x + 8 * cellWidth, y + 8 + rows * cellHeight);
g.drawLine(x + 4 * cellWidth, y + 9 + rows * cellHeight, x + 8 * cellWidth, y + 9 + rows * cellHeight);
break;
}
switch(rows) {
case 2:
g.drawLine(x - 8, y + cellHeight, x - 8, y + 2 * cellHeight);
g.drawLine(x - 9, y + cellHeight, x - 9, y + 2 * cellHeight);
break;
case 4:
g.drawLine(x - 8, y + 2 * cellHeight, x - 8, y + 4 * cellHeight);
g.drawLine(x - 9, y + 2 * cellHeight, x - 9, y + 4 * cellHeight);
g.drawLine(x + cols * cellWidth + 8, y + cellHeight, x + cols * cellWidth + 8, y + 3 * cellHeight);
g.drawLine(x + cols * cellWidth + 9, y + cellHeight, x + cols * cellWidth + 9, y + 3 * cellHeight);
break;
}
int outputColumn = table.getOutputIndex(output);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int row = getTableRow(i, j, rows, cols);
Entry entry = table.getOutputEntry(row, outputColumn);
if (provisionalValue != null && row == provisionalY && outputColumn == provisionalX)
entry = provisionalValue;
if (entry.isError()) {
g.setColor(ERROR_COLOR);
g.fillRect(x + j * cellWidth, y + i * cellHeight, cellWidth, cellHeight);
g.setColor(Color.BLACK);
}
g.drawRect(x + j * cellWidth, y + i * cellHeight, cellWidth, cellHeight);
g.drawRect(x + j * cellWidth + 1, y + i * cellHeight + 1, cellWidth - 2, cellHeight - 2);
}
}
g.drawRect(x, y, cols * cellWidth, rows * cellHeight);
g.drawRect(x - 1, y - 1, cols * cellWidth + 2, rows * cellHeight + 2);
List<Implicant> implicants = model.getOutputExpressions().getMinimalImplicants(output);
if (implicants != null) {
int index = 0;
for (Implicant imp : implicants) {
g.setColor(IMP_COLORS[index % IMP_COLORS.length]);
paintImplicant(g, imp, x, y, rows, cols);
index++;
}
}
if (outputColumn < 0)
return;
g.setColor(Color.BLUE);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int row = getTableRow(i, j, rows, cols);
if (provisionalValue != null && row == provisionalY && outputColumn == provisionalX) {
String text = provisionalValue.getDescription();
g.setColor(Color.ORANGE);
g.drawString(text, x + j * cellWidth + (cellWidth - fm.stringWidth(text)) / 2, y + i * cellHeight + dy);
g.setColor(Color.BLUE);
} else {
Entry entry = table.getOutputEntry(row, outputColumn);
String text = entry.getDescription();
g.drawString(text, x + j * cellWidth + (cellWidth - fm.stringWidth(text)) / 2, y + i * cellHeight + dy);
}
}
}
}
Aggregations