绘图板程序设计及其具体实现 第五篇

图形元素包详细解析

ImageElement类

ImageElement类是所有图形元素类的父类,默认颜色为黑色,默认为非空,且有一个抽象函数draw,参数为绘制的Graphics对象和坐标转换矩阵,表示当前图形元素的绘制策略。

  • ImageElement类源代码
package Rendering.element;

import Rendering.utils.Matrix3x3f;

import java.awt.*;

public abstract class ImageElement {
    protected Color color = Color.BLACK;

    public boolean empty() {
        return false;
    }

    public abstract void draw(Graphics2D g2d, Matrix3x3f view);
}

Points类

Points类表示一系列点的集合,由一个列表来存储所有的点,并拥有以下方法:

  • public boolean addPoint(Vector2f point):添加一个点

  • public void draw(Graphics2D g2d, Matrix3x3f view):在指定画布上根据坐标转换矩阵绘制

  • public Points remove():移除一些连续的点,即移除一条曲线

  • public boolean empty():列表中不包含任何点时则表示此对象为空

  • Points类源代码

package Rendering.element;

import Rendering.utils.Matrix3x3f;
import Rendering.utils.Utility;
import Rendering.utils.Vector2f;

import java.awt.*;
import java.util.Vector;

public class Points extends ImageElement {
    private Vector<Vector2f> points = new Vector<>();

    public Points() {}

    public Points(Color color) {
        this.color = color;
    }

    public boolean addPoint(Vector2f point) {
        return points.add(point);
    }

    @Override
    public void draw(Graphics2D g2d, Matrix3x3f view) {
        if (points.size() > 0) {
            Vector2f P = points.get(0);
            Vector2f S;
            for (int i = 1; i < points.size(); i++) {
                S = points.get(i);
                if (!(P == null || S == null)) {
                    Utility.drawPolygon(g2d, new Vector2f[]{P, S},
                            view, color);
                }
                P = S;
            }
        }
    }

    public Points remove() {
        if (points.size() > 0 && points.get(points.size() - 1) == null) {
            points.remove(points.size() - 1);
        }
        while (points.size() > 0) {
            Vector2f tmp = points.remove(points.size() - 1);
            if (tmp == null) {
                return this;
            }
        }
        return this;
    }

    @Override
    public boolean empty() {
        return points.size() == 0;
    }
}

Similarable接口

Similarable接口声明了快捷选择操作接口(API),包含一个EPSILON字段和一个similar函数。快捷选择操作的理念是:当你想要选择到一个特殊点时,例如一条线段的中点,直接通过肉眼来使用鼠标点击的方式并不准确,所以本程序中设置了当鼠标距离一个特殊点的距离足够近时,会有选择特殊点的提示,通过单击鼠标的滚轮,可以快捷选择到这个特殊点。

  • EPSILON字段表示快捷选择操作可以执行时距离特殊点的最小距离。
  • similar函数的参数为鼠标当前位置的世界坐标,返回值为当前可以快捷选择到的点,若没有这样的点则返回值为空。
  • Similarable接口源代码
package Rendering.element;

import Rendering.utils.Vector2f;

public interface Similarable {
    public static final float EPSILON = 0.2f;

    public abstract Vector2f similar(Vector2f v);
}

BeginEndImageElement类

BeginEndImageElement类是本程序中使用到的最重要的一个图形元素类,它继承了ImageElement类,实现了Similarable接口,表示这个图形元素是可以执行快捷选择操作的。(关于快捷选择操作的具体实现,后续会详细介绍)这个图形元素类代表了所有的可以通过起点拖动到终点绘制的图形元素。包含,线段,矩形,等边三角形,圆和椭圆

BeginEndImageElement类除了必须的构造函数和继承自父类的draw函数之外,新增了两个字段,begin和end,分别表示图形元素的起点和终点;重载了empty方法,当两个点没有全部确定或两个点相同时则判定为空。这个类在后面并没有具体实现,而只是在每次具体绘制时使用匿名类的方式实现具体的绘制函数,这样减少了很多代码量,也使程序更加简洁明了。

  • BeginEndImageElement类源代码
package Rendering.element;

import Rendering.utils.Matrix3x3f;
import Rendering.utils.Vector2f;

import java.awt.*;

public abstract class BeginEndImageElement
        extends ImageElement implements Similarable {
    protected Vector2f begin;
    protected Vector2f end;

    public BeginEndImageElement(Vector2f begin, Vector2f end) {
        this.begin = begin;
        this.end = end;
    }

    public BeginEndImageElement(Vector2f begin, Vector2f end, Color color) {
        this(begin, end);
        this.color = color;
    }

    @Override
    public abstract void draw(Graphics2D g2d, Matrix3x3f view);
    
    @Override
    public boolean empty() {
        if (begin == null || end == null) {
            return true;
        } else {
            return begin.equals(end);
        }
    }
}

FillPolygon类

FillPolygon类表示填充多边形类,它继承了ImageElement类,实现了Similarable接口。**因为快捷选择操作的存在,多边形可以通过线段的连接来绘制,但是填充多边形则不可以,所以在本程序中对填充多边形做特殊处理。**这是本程序中除了点列只外第二个不能由起点拖动到终点绘制的图形元素,也是本程序中实现最复杂的一个图形元素。

  • FillPolygon类字段一览表
修饰符类型名称说明
protectedVector< Vector2f>polygon表示填充多边形中的点
protectedbooleanclosed表示填充多边形是否闭合,即是否完成绘制
  • FillPolygon类方法一览表
修饰符返回值函数名参数说明
publicFillPolygon()默认构造函数,默认颜色为继承自父类的黑色
publicFillPolygon(Color color)构造函数
publicFillPolygon(FillPolygon fillPolygon,Color color)构造函数,更改颜色时调用
publicbooleanaddPoint(Vector2f point)向填充多边形中添加一个点
publicbooleanremovePoint()在填充多边形中删除一个点
publicvoidclose()设置填充多边形闭合
publicbooleanisClosed()返回填充多边形是否闭合
publicvoiddraw(Graphics2D g2d,Matrix3x3f view)实现了父类的具体的绘制策略
publicbooleanempty()返回是否为空,当点数小于2时判定为空
publicVector2fsimilar(Vector2f mousePos)实现了快捷选择操作接口(API),可以快捷选择到填充多边形上的所有点
  • FillPolygon类源代码
package Rendering.element;

import Rendering.utils.Matrix3x3f;
import Rendering.utils.Utility;
import Rendering.utils.Vector2f;

import java.awt.*;
import java.util.Vector;

public class FillPolygon
        extends ImageElement implements Similarable {
    protected Vector<Vector2f> polygon = new Vector<>();
    protected boolean closed = false;

    public FillPolygon() {}

    public FillPolygon(Color color) {
        this.color = color;
    }

    public FillPolygon(FillPolygon fillPolygon, Color color) {
        this(color);
        polygon = fillPolygon.polygon;
        closed = fillPolygon.isClosed();
    }

    public boolean addPoint(Vector2f point) {
        return polygon.add(point);
    }

    public boolean removePoint() {
        if (closed) {
            closed = false;
            return true;
        } else if (polygon.size() > 0) {
            polygon.remove(polygon.size() - 1);
            return true;
        } else {
            return false;
        }
    }

    public void close() {
        closed = true;
    }

    public boolean isClosed() {
        return closed;
    }

    @Override
    public void draw(Graphics2D g2d, Matrix3x3f view) {
        if (polygon.size() > 2 && closed) {
            Utility.fillPolygon(g2d, polygon, view, color);
        } else if (polygon.size() > 0) {
            Vector2f P = polygon.get(0);
            Vector2f S;
            for (int i = 0; i < polygon.size(); i++) {
                S = polygon.get(i);
                Utility.drawPolygon(g2d, new Vector2f[]{P, S}, view, color);
                P = S;
            }
        }
    }

    @Override
    public boolean empty() {
        return polygon.size() < 2;
    }

    @Override
    public Vector2f similar(Vector2f mousePos) {
        for (Vector2f v : polygon) {
            if (v.similar(mousePos, EPSILON)) {
                return v;
            }
        }
        return null;
    }
}

StringElement类

StringElement类是表示字符串绘制的类,它继承了ImageElement类,新增了两个字段——字符串左上角的位置和字符串的内容,且实现了父类的具体的绘制策略。

  • StringElement类源代码
package Rendering.element;

import Rendering.utils.Matrix3x3f;
import Rendering.utils.Utility;
import Rendering.utils.Vector2f;

import java.awt.*;

public class StringElement extends ImageElement {
    protected Vector2f position;
    protected String message;

    public StringElement(Vector2f position, String message) {
        this.position = position;
        this.message = message;
    }

    public StringElement(Vector2f position, String message, Color color) {
        this(position, message);
        this.color = color;
    }

    @Override
    public void draw(Graphics2D g2d, Matrix3x3f view) {
        Utility.drawPolygon(g2d, new Vector2f[]{position}, view, color);
        Utility.drawString(g2d, position, view, color, message);
    }
}

SaveImageElement类

SaveImageElement类继承了ImageElement类,但是没有做任何的具体实现。在绘制过程中,图形元素列表顶端插入一个SaveImageElement实例以表示之前的所有图形元素已经保存。

  • SaveImageElement类源代码
package Rendering.element;

import Rendering.utils.Matrix3x3f;

import java.awt.*;

public class SaveImageElement extends ImageElement {
    @Override
    public void draw(Graphics2D g2d, Matrix3x3f view) {}
}

更多:

第一篇
第二篇
第三篇
第四篇
第五篇
第六篇
第七篇
最终篇
源代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值