在上篇文章中我们已经通过Graphics2D绘制了大部分的形状,但是在现实需求中,可能需要我们绘制各式各样的形状,这个时候我们就需要用到GeneralPath这个类。
上篇文章传送门:https://blog.csdn.net/u011837804/article/details/129504353
本篇文章我们讲解GeneralPath类的详细使用方法,调用方法说明,以及通过绘制绘制不规则形状、绘制不规则形状并且自动闭合、绘制菱形、绘制五角星实例代码详解绘制任意形状。
其中绘制五角星是真的复杂,因为五角星有10个坐标点需要动态计算,但是考虑到自己国家的国徽必须绘制出来,经过几天的学习研究,总于搞定,吐血分享出来,全网几乎找不到java绘制的参考点,如果觉得有用的朋友一定点赞加关注,感谢。
GeneralPath构造函数说明
/**
* Constructs a new {@code GeneralPath} object with the specified
* winding rule and the specified initial capacity to store path
* coordinates.
* This number is an initial guess as to how many path segments
* will be added to the path, but the storage is expanded as
* needed to store whatever path segments are added.
*
* @param rule the winding rule 绕线规则(没有太懂,两个枚举没看出不一致的地方)
* @param initialCapacity the estimate for the number of path segments
* in the path 初始整个绘制过程中会绘制几条线
* @throws IllegalArgumentException if {@code rule} is not either
* {@link #WIND_EVEN_ODD} or {@link #WIND_NON_ZERO}
* @throws NegativeArraySizeException if {@code initialCapacity} is
* negative
* @see #WIND_EVEN_ODD
* @see #WIND_NON_ZERO
* @since 1.2
*/
public GeneralPath(int rule, int initialCapacity) {
super(rule, initialCapacity);
}
要创建空GeneralPath实例调用new GeneralPath(),然后使用以下方法向形状添加线段:
-
moveTo(float x, float y)– 将路径的当前点移动到给定点
假如当前画笔是在(10,10)坐标位置,直接将画笔移动至(x,y)坐标点,注意是移动,这两点之间不划线
-
lineTo(float x, float y)– 向当前路径添加线段
假如当前画笔是在(10,10)坐标位置,直接将画笔移动至(x,y)坐标点,并且在(10,10)到(x,y)之间画一条线
-
quadTo(float ctrlx, float ctrly, float x2, floaty2)– 将二次曲线段添加到当前路径
-
curveTo(float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x3, floaty3)– 将三次曲线段添加到当前路径
-
closePath()– 关闭当前路径
就是将开始坐标和结束坐标用线连接起来
下面我们看几个实例
①、实例一:绘制不规则形状
代码:
BufferedImage image = loadImage();
Graphics2D graphics2D = image.createGraphics();
graphics2D.setColor(Color.RED);
/**
* 设置需要绘制的点
* x2Points和y2Points 两个数组长度一直,相同下标数值分别表示一个点的x和y轴
* 本例有4个点(0,0) (100,50) (0,50) (100,0)
*/
int x2Points[] = {0, 100, 0, 100};
int y2Points[] = {0, 50, 50, 0};
GeneralPath polyline =
new GeneralPath(GeneralPath.WIND_NON_ZERO, x2Points.length);
//画笔移动至 (0,0)坐标
polyline.moveTo(x2Points[0], y2Points[0]);
//然后从 (0,0)坐标开始 按顺序 绘制到目标点的线
for (int index = 1; index < x2Points.length; index++) {
polyline.lineTo(x2Points[index], y2Points[index]);
}
graphics2D.draw(polyline);
graphics2D.dispose();
image.flush();
ImgUtil.write(image, new File(SAVE_FILE_PATH + "GeneralPath1.png"));
效果:

②、实例二:绘制不规则形状并且闭合
代码:相比实例一多出了”polyline.closePath();“效果就不一致
BufferedImage image = loadImage();
Graphics2D graphics2D = image.createGraphics();
graphics2D.setColor(Color.RED);
/**
* 设置需要绘制的点
* x2Points和y2Points 两个数组长度一直,相同下标数值分别表示一个点的x和y轴
* 本例有4个点(0,0) (100,50) (0,50) (100,0)
*/
int x2Points[] = {5, 100, 0, 100};
int y2Points[] = {5, 50, 50, 0};
GeneralPath polyline =
new GeneralPath(GeneralPath.WIND_NON_ZERO, x2Points.length);
//画笔移动至 (0,0)坐标
polyline.moveTo(x2Points[0], y2Points[0]);
//然后从 (0,0)坐标开始 按顺序 绘制到目标点的线
for (int index = 1; index < x2Points.length; index++) {
polyline.lineTo(x2Points[index], y2Points[index]);
}
polyline.closePath();
graphics2D.draw(polyline);
graphics2D.dispose();
image.flush();
ImgUtil.write(image, new File(SAVE_FILE_PATH + "GeneralPath2.png"));

③、实例三:绘制菱形
代码:
BufferedImage image = loadImage();
Graphics2D graphics2D = image.createGraphics();
graphics2D.setColor(Color.RED);
/**
* 设置需要绘制的点
* x2Points和y2Points 两个数组长度一直,相同下标数值分别表示一个点的x和y轴
* 本例有4个点(5,55) (55,5) (105,55) (55,105)
*/
int x2Points[] = {5, 55, 105, 55};
int y2Points[] = {55, 5, 55, 105};
GeneralPath polyline =
new GeneralPath(GeneralPath.WIND_NON_ZERO, x2Points.length);
//画笔移动至 (0,0)坐标
polyline.moveTo(x2Points[0], y2Points[0]);
//然后从 (0,0)坐标开始 按顺序 绘制到目标点的线
for (int index = 1; index < x2Points.length; index++) {
polyline.lineTo(x2Points[index], y2Points[index]);
}
polyline.closePath();
graphics2D.draw(polyline);
graphics2D.dispose();
image.flush();
ImgUtil.write(image, new File(SAVE_FILE_PATH + "GeneralPath3.png"));
绘制效果:


④、实例四:绘制五角星
五角星的绘制复杂的地方是在10个坐标点的计算,直接上代码
计算五角星10个坐标点的方法代码
/**
* 计算五角星10个坐标位置
*
* @param centerX 五角星中心点X轴
* @param centerY 五角星中心点Y轴
* @param x2Points 存储五角星10个点X轴
* @param y2Points 存储五角星10个点Y轴
* 需要注意的是 第一个坐标必须指定
* @return void
* @author liuchao
* @date 2023/3/14
*/
private void calculateFivePointedStarPoint(double centerX, double centerY, double x2Points[], double y2Points[]) {
//圆周率
float pi = 3.141592653F;
x2Points[1] = centerX - (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.cos((float) 36 / 360 * 2 * pi + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[1] = centerY + (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.sin((float) 36 / 360 * 2 * pi + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
x2Points[2] = centerX - (float) 30 *
Math.cos((float) 36 / 360 * 2 * pi * 2 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[2] = centerY + (float) 30 *
Math.sin((float) 36 / 360 * 2 * pi * 2 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
x2Points[3] = centerX - (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.cos((float) 36 / 360 * 2 * pi * 3 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[3] = centerY + (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.sin((float) 36 / 360 * 2 * pi * 3 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
x2Points[4] = centerX - (float) 30 *
Math.cos((float) 36 / 360 * 2 * pi * 4 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[4] = centerY + (float) 30 *
Math.sin((float) 36 / 360 * 2 * pi * 4 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
x2Points[5] = centerX - (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.cos((float) 36 / 360 * 2 * pi * 5 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[5] = centerY + (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.sin((float) 36 / 360 * 2 * pi * 5 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
x2Points[6] = centerX - (float) 30 *
Math.cos((float) 36 / 360 * 2 * pi * 6 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[6] = centerY + (float) 30 *
Math.sin((float) 36 / 360 * 2 * pi * 6 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
x2Points[7] = centerX - (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.cos((float) 36 / 360 * 2 * pi * 7 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[7] = centerY + (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.sin((float) 36 / 360 * 2 * pi * 7 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
x2Points[8] = centerX - (float) 30 *
Math.cos((float) 36 / 360 * 2 * pi * 8 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[8] = centerY + (float) 30 *
Math.sin((float) 36 / 360 * 2 * pi * 8 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
x2Points[9] = centerX - (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.cos((float) 36 / 360 * 2 * pi * 9 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
y2Points[9] = centerY + (float) 10 / Math.cos((float) 36 / 360 * 2 * pi) *
Math.sin((float) 36 / 360 * 2 * pi * 9 + Math.atan((float) Math.abs(y2Points[0] - centerY)
/ (float) Math.abs(x2Points[0] - centerX)));
}
绘制五角星代码
/**
* 五角星中心点位置
*/
double centerX = 300D;
double centerY = 60D;
/**
* 五角星10个点坐标
* 第一个点坐标必须指定
*/
double x2Points[] = {274D, 0D, 0D, 0D, 0D, 0D, 0D, 0D, 0D, 0D};
double y2Points[] = {75D, 0D, 0D, 0D, 0D, 0D, 0D, 0D, 0D, 0D};
calculateFivePointedStarPoint(centerX, centerY, x2Points, y2Points);
BufferedImage image = loadImage();
Graphics2D graphics2D = image.createGraphics();
graphics2D.setColor(Color.RED);
GeneralPath polyline =
new GeneralPath(GeneralPath.WIND_NON_ZERO, x2Points.length);
//画笔移动至 (0,0)坐标
polyline.moveTo(x2Points[0], y2Points[0]);
//然后从 (0,0)坐标开始 按顺序 绘制到目标点的线
for (int index = 1; index < x2Points.length; index++) {
polyline.lineTo(x2Points[index], y2Points[index]);
}
polyline.closePath();
graphics2D.draw(polyline);
graphics2D.dispose();
image.flush();
ImgUtil.write(image, new File(SAVE_FILE_PATH + "five-pointed-star.png"));
绘制效果:

大家看到五角星10个坐标点的计算方法是不是懵逼了,没错就是这么复杂,觉得有用的朋友一定要点赞加关注,感谢!!!!!!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/144611.html