Processing椭圆连线开发问题:首尾无法正确连接及原点存储疑问
搞定Processing点击绘椭圆+闭合连线的问题
嘿,我来帮你解决这个问题~先说说你当前代码里的两个关键bug:
- 初始点坐标错了:你在全局变量里直接给
OriginalX和OriginalY赋值为mouseX/mouseY,但程序刚启动时还没创建窗口,mouseX和mouseY默认是0,所以连线会从左上角(0,0)出发,这就是你看到的奇怪现象。 - 没法保存所有点:用单个变量
PrevX/PrevY只能记住上一个点,没法存下所有点击的坐标,自然没法正确把最后一个点和第一个点连起来。
咱们换个思路,用Processing的ArrayList<PVector>来存储所有点击的坐标——PVector是专门存二维坐标的工具类,ArrayList可以动态添加元素,完美适配这种不确定点击次数的场景。下面是修正后的代码:
// 用ArrayList存储所有点击的点,PVector帮我们打包x和y坐标 ArrayList<PVector> points = new ArrayList<PVector>(); final int N_PARTITIONS = 10; void setup() { size(600, 360); surface.setResizable(true); } void draw() { // 这里留空也可以,如果需要窗口缩放后重绘图形,就加上下面这句 // background(255); } void mouseClicked() { // 把当前点击的坐标存进数组 PVector currentPoint = new PVector(mouseX, mouseY); points.add(currentPoint); // 画当前点击位置的椭圆 ellipse(mouseX, mouseY, N_PARTITIONS, N_PARTITIONS); // 至少有两个点时,连当前点和上一个点 if (points.size() >= 2) { PVector prevPoint = points.get(points.size() - 2); line(prevPoint.x, prevPoint.y, currentPoint.x, currentPoint.y); } // 当有至少两个点时,把最后一个点和第一个点连起来,形成闭合图形 // 如果你想点击3次以上才闭合,就把条件改成points.size() >= 3 if (points.size() >= 2) { PVector firstPoint = points.get(0); PVector lastPoint = points.get(points.size() - 1); line(firstPoint.x, firstPoint.y, lastPoint.x, lastPoint.y); } }
关键改动说明:
- 用ArrayList存所有点:每次点击都把鼠标坐标包装成PVector对象存起来,这样所有点的位置都不会丢,想连哪个点都能拿到。
- 修正初始点问题:不再用全局变量存初始点,直接从ArrayList的第一个元素取,确保是你第一次点击的真实坐标。
- 灵活的连线逻辑:
- 每次点击后,只要有两个以上的点,就自动连当前点和上一个点,实现依次连线的效果。
- 同时连接最后一个点和第一个点,实现闭合图形(你可以根据需求调整闭合的条件,比如点击3次才闭合)。
如果希望窗口缩放后图形不丢失,可以把绘制逻辑移到draw()里,加上背景刷新,这个版本更健壮:
ArrayList<PVector> points = new ArrayList<PVector>(); final int N_PARTITIONS = 10; void setup() { size(600, 360); surface.setResizable(true); } void draw() { background(255); // 刷新背景,避免重叠 // 画所有已点击的椭圆 for (PVector p : points) { ellipse(p.x, p.y, N_PARTITIONS, N_PARTITIONS); } // 画所有连线+闭合首尾 if (points.size() >= 2) { // 连相邻的点 for (int i = 1; i < points.size(); i++) { PVector prev = points.get(i-1); PVector curr = points.get(i); line(prev.x, prev.y, curr.x, curr.y); } // 连最后一个点和第一个点 PVector first = points.get(0); PVector last = points.get(points.size()-1); line(first.x, first.y, last.x, last.y); } } void mouseClicked() { points.add(new PVector(mouseX, mouseY)); }
这个版本里,每次draw()都会重新绘制所有图形,窗口调整大小后也不会丢失内容~
内容的提问来源于stack exchange,提问作者UwUvibes
相关产品推荐
相关产品推荐

