Search in sources :

Example 1 with Implicant

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);
    }
}
Also used : Implicant(com.cburch.logisim.analyze.model.Implicant)

Example 2 with Implicant

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);
            }
        }
    }
}
Also used : Entry(com.cburch.logisim.analyze.model.Entry) Implicant(com.cburch.logisim.analyze.model.Implicant) FontMetrics(java.awt.FontMetrics) TruthTable(com.cburch.logisim.analyze.model.TruthTable) Dimension(java.awt.Dimension) Graphics2D(java.awt.Graphics2D)

Aggregations

Implicant (com.cburch.logisim.analyze.model.Implicant)2 Entry (com.cburch.logisim.analyze.model.Entry)1 TruthTable (com.cburch.logisim.analyze.model.TruthTable)1 Dimension (java.awt.Dimension)1 FontMetrics (java.awt.FontMetrics)1 Graphics2D (java.awt.Graphics2D)1