ConsoleRenderer.java

package com.example.graphics.render;

import com.example.graphics.model.Circle;
import com.example.graphics.model.Line;
import com.example.graphics.model.Rectangle;
import com.example.graphics.model.Triangle;

/**
 * Console text-based implementation of the Renderer interface.
 * Part of the Bridge pattern.
 */
public class ConsoleRenderer implements Renderer {
    private final int width;
    private final int height;
    private char[][] canvas;
    
    /**
     * Constructor initializes the console renderer with specified dimensions
     * @param width the width of the canvas
     * @param height the height of the canvas
     */
    public ConsoleRenderer(int width, int height) {
        this.width = width;
        this.height = height;
        clear();
    }
    
    @Override
    public void renderCircle(Circle circle) {
        int x0 = circle.getX();
        int y0 = circle.getY();
        int radius = circle.getRadius();
        
        // Using Bresenham's circle algorithm
        int x = radius;
        int y = 0;
        int err = 0;
        
        while (x >= y) {
            drawPixel(x0 + x, y0 + y);
            drawPixel(x0 + y, y0 + x);
            drawPixel(x0 - y, y0 + x);
            drawPixel(x0 - x, y0 + y);
            drawPixel(x0 - x, y0 - y);
            drawPixel(x0 - y, y0 - x);
            drawPixel(x0 + y, y0 - x);
            drawPixel(x0 + x, y0 - y);
            
            y += 1;
            if (err <= 0) {
                err += 2 * y + 1;
            }
            if (err > 0) {
                x -= 1;
                err -= 2 * x + 1;
            }
        }
    }
    
    @Override
    public void renderRectangle(Rectangle rectangle) {
        int x = rectangle.getX();
        int y = rectangle.getY();
        int w = rectangle.getWidth();
        int h = rectangle.getHeight();
        
        // Draw horizontal lines
        for (int i = x; i < x + w; i++) {
            drawPixel(i, y);
            drawPixel(i, y + h - 1);
        }
        
        // Draw vertical lines
        for (int i = y; i < y + h; i++) {
            drawPixel(x, i);
            drawPixel(x + w - 1, i);
        }
    }
    
    @Override
    public void renderLine(Line line) {
        int x1 = line.getX1();
        int y1 = line.getY1();
        int x2 = line.getX2();
        int y2 = line.getY2();
        
        // Using Bresenham's line algorithm
        int dx = Math.abs(x2 - x1);
        int dy = Math.abs(y2 - y1);
        int sx = x1 < x2 ? 1 : -1;
        int sy = y1 < y2 ? 1 : -1;
        int err = dx - dy;
        
        while (true) {
            drawPixel(x1, y1);
            
            if (x1 == x2 && y1 == y2) break;
            
            int e2 = 2 * err;
            if (e2 > -dy) {
                if (x1 == x2) break;
                err -= dy;
                x1 += sx;
            }
            if (e2 < dx) {
                if (y1 == y2) break;
                err += dx;
                y1 += sy;
            }
        }
    }
    
    @Override
    public void renderTriangle(Triangle triangle) {
        // 使用三条线来绘制三角形
        int x1 = triangle.getX1();
        int y1 = triangle.getY1();
        int x2 = triangle.getX2();
        int y2 = triangle.getY2();
        int x3 = triangle.getX3();
        int y3 = triangle.getY3();
        
        // 绘制第一条边
        drawLine(x1, y1, x2, y2);
        
        // 绘制第二条边
        drawLine(x2, y2, x3, y3);
        
        // 绘制第三条边
        drawLine(x3, y3, x1, y1);
    }
    
    @Override
    public void clear() {
        canvas = new char[height][width];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                canvas[y][x] = ' ';
            }
        }
    }
    
    @Override
    public void display() {
        System.out.println("Console Renderer Output:");
        // Print top border
        System.out.print('+');
        for (int x = 0; x < width; x++) {
            System.out.print('-');
        }
        System.out.println('+');
        
        // Print canvas with borders
        for (int y = 0; y < height; y++) {
            System.out.print('|');
            for (int x = 0; x < width; x++) {
                System.out.print(canvas[y][x]);
            }
            System.out.println('|');
        }
        
        // Print bottom border
        System.out.print('+');
        for (int x = 0; x < width; x++) {
            System.out.print('-');
        }
        System.out.println('+');
    }
    
    /**
     * Draw a pixel at the specified coordinates
     * @param x the x coordinate
     * @param y the y coordinate
     */
    private void drawPixel(int x, int y) {
        if (x >= 0 && x < width && y >= 0 && y < height) {
            canvas[y][x] = '*';
        }
    }
    
    /**
     * Draw a line between two points
     * @param x1 the x coordinate of the first point
     * @param y1 the y coordinate of the first point
     * @param x2 the x coordinate of the second point
     * @param y2 the y coordinate of the second point
     */
    private void drawLine(int x1, int y1, int x2, int y2) {
        // Using Bresenham's line algorithm
        int dx = Math.abs(x2 - x1);
        int dy = Math.abs(y2 - y1);
        int sx = x1 < x2 ? 1 : -1;
        int sy = y1 < y2 ? 1 : -1;
        int err = dx - dy;
        
        while (true) {
            drawPixel(x1, y1);
            
            if (x1 == x2 && y1 == y2) break;
            
            int e2 = 2 * err;
            if (e2 > -dy) {
                if (x1 == x2) break;
                err -= dy;
                x1 += sx;
            }
            if (e2 < dx) {
                if (y1 == y2) break;
                err += dx;
                y1 += sy;
            }
        }
    }
}