用Java实现可交互的贝塞尔曲线(Bezier curve)

article/2025/11/9 19:54:15

关于贝塞尔曲线的详细数学原理及公式可参考:

贝塞尔曲线_百度百科

我们来谈谈贝塞尔曲线

 

 本文给出了一种用Java实现贝塞尔曲线的方法,并且可以用鼠标拖动改变锚点。

效果演示图:

这里引用百度百科给出的公式:

二次方公式

三次方公式

核心算法代码:

// 二次贝塞尔曲线
for (double k = t; k <= 1 + t; k += t) {double r = 1 - k;x = Math.pow(r, 2) * keyPointP[0].getX() + 2 * k * r * keyPointP[1].getX()+ Math.pow(k, 2) * keyPointP[2].getX();y = Math.pow(r, 2) * keyPointP[0].getY() + 2 * k * r * keyPointP[1].getY()+ Math.pow(k, 2) * keyPointP[2].getY();g.drawOval((int) x, (int) y, 1, 1);// 画圆的方式比下面注释掉的画线效果更好// g.drawLine((int) x, (int) y, (int) x, (int) y);
}
// 三次贝塞尔曲线
for (double k = t; k <= 1 + t; k += t) {double r = 1 - k;x = Math.pow(r, 3) * keyPointP[0].getX() + 3 * k * Math.pow(r, 2) * keyPointP[1].getX()+ 3 * Math.pow(k, 2) * (1 - k) * keyPointP[2].getX() + Math.pow(k, 3) * keyPointP[3].getX();y = Math.pow(r, 3) * keyPointP[0].getY() + 3 * k * Math.pow(r, 2) * keyPointP[1].getY()+ 3 * Math.pow(k, 2) * (1 - k) * keyPointP[2].getY() + Math.pow(k, 3) * keyPointP[3].getY();g.drawOval((int) x, (int) y, 1, 1);
}

 

完整代码:

package test;import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;import javax.swing.JFrame;
import javax.swing.JPanel;/*** @author: happyaaakkk* @date : 2020年4月28日* @Description:贝塞尔曲线测试*/
public class TestBezier {/*** 存关键点的x、y的数组*/private static Point2D[] keyPointP;/*** 存关键点的x、y、width、height的数组*/private static Ellipse2D.Double[] keyPointE;/*** 关键点数*/private static int keyPointNum;/*** 偏移量,越小曲线越精细*/private static double t = 0.001;/*** 显示蓝色辅助线的标记*/private static boolean flagShow = true;static class BezierPanel extends JPanel {/*** */private static final long serialVersionUID = 1L;/*** 关键点编号*/private int keyPointID = -1;BezierPanel() {this.addMouseListener(new MouseAction());this.addMouseMotionListener(new MouseMotion());}@Overrideprotected void paintComponent(Graphics gs) {// 重写repaintsuper.paintComponent(gs);Graphics2D g = (Graphics2D) gs;g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g.setColor(Color.BLUE);if (flagShow) {for (int i = 0; i < keyPointNum; i++) { // 绘制圆点if (i > 0 && i < (keyPointNum - 1)) {g.fill(keyPointE[i]);// 中间的关键点画实心圆} else {g.draw(keyPointE[i]);// 第一个和最后一个画空心圆}if (keyPointNum > 1 && i < (keyPointNum - 1)) {g.drawLine((int) keyPointP[i].getX(), (int) keyPointP[i].getY(), (int) keyPointP[i + 1].getX(),(int) keyPointP[i + 1].getY());// 画关键点之间连接的直线}if (i == 0) {g.drawString("A", (int) keyPointE[i].x, (int) keyPointE[i].y);} else if (i == 1) {g.drawString("B", (int) keyPointE[i].x, (int) keyPointE[i].y);} else if (i == 2) {g.drawString("C", (int) keyPointE[i].x, (int) keyPointE[i].y);} else if (i == 3) {g.drawString("D", (int) keyPointE[i].x, (int) keyPointE[i].y);}}}// 二次贝塞尔曲线if (keyPointNum == 3) {double x, y;g.setColor(Color.RED);for (double k = t; k <= 1 + t; k += t) {double r = 1 - k;x = Math.pow(r, 2) * keyPointP[0].getX() + 2 * k * r * keyPointP[1].getX() + Math.pow(k, 2) * keyPointP[2].getX();y = Math.pow(r, 2) * keyPointP[0].getY() + 2 * k * r * keyPointP[1].getY() + Math.pow(k, 2) * keyPointP[2].getY();g.drawOval((int) x, (int) y, 1, 1);// 画圆的方式比下面注释掉的画线效果更好// g.drawLine((int) x, (int) y, (int) x, (int) y);}}// 三次贝塞尔曲线if (keyPointNum == 4) {double x, y;g.setColor(Color.RED);for (double k = t; k <= 1 + t; k += t) {double r = 1 - k;x = Math.pow(r, 3) * keyPointP[0].getX() + 3 * k * Math.pow(r, 2) * keyPointP[1].getX()+ 3 * Math.pow(k, 2) * (1 - k) * keyPointP[2].getX() + Math.pow(k, 3) * keyPointP[3].getX();y = Math.pow(r, 3) * keyPointP[0].getY() + 3 * k * Math.pow(r, 2) * keyPointP[1].getY()+ 3 * Math.pow(k, 2) * (1 - k) * keyPointP[2].getY() + Math.pow(k, 3) * keyPointP[3].getY();g.drawOval((int) x, (int) y, 1, 1);}}}class MouseAction extends MouseAdapter {@Overridepublic void mouseClicked(MouseEvent e) {// 点击鼠标左键if (e.getButton() == MouseEvent.BUTTON1) {if (keyPointNum < 4) {double x = e.getX();double y = e.getY();keyPointP[keyPointNum] = new Point2D.Double(x, y);keyPointE[keyPointNum] = new Ellipse2D.Double(x - 4, y - 4, 8, 8);keyPointNum++;repaint();}} // 点击鼠标右键else if (e.getButton() == MouseEvent.BUTTON3) {flagShow = false;// 隐藏蓝色辅助线,但并不能真正移除repaint();}}@Overridepublic void mousePressed(MouseEvent e) {// 按下鼠标,判断是不是点击了关键点for (int i = 0; i < keyPointNum; i++) {if (keyPointE[i].contains((Point2D) e.getPoint())) {keyPointID = i;break;} else {keyPointID = -1;}}}}class MouseMotion extends MouseMotionAdapter {@Overridepublic void mouseDragged(MouseEvent e) {// 鼠标拖动关键点if (keyPointID != -1) {double x = e.getX();double y = e.getY();keyPointP[keyPointID] = new Point2D.Double(x, y);keyPointE[keyPointID] = new Ellipse2D.Double(x - 4, y - 4, 8, 8);repaint();}}}}public TestBezier() {JFrame f = new JFrame();f.setTitle("Bezier Test");f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setSize(800, 600);f.setLocationRelativeTo(null);keyPointNum = 0;keyPointP = new Point2D[4];keyPointE = new Ellipse2D.Double[4];BezierPanel bezierPanel = new BezierPanel();bezierPanel.setPreferredSize(new Dimension(800, 600));bezierPanel.setBackground(Color.WHITE);f.setContentPane(bezierPanel);f.setVisible(true);}public static void main(String[] agrs) {new TestBezier();}
}

 

 


http://chatgpt.dhexx.cn/article/q0c4Ji9a.shtml

相关文章

Bezier曲线简介

Bezier曲线简介 Bezier曲线&#xff0c;又有人叫贝赛尔曲线&#xff0c;贝兹曲线&#xff0c;在计算机绘图中经常被用到&#xff0c;由于前些天事件要用到这个&#xff0c;所以就研究了下。 有了参考资料&#xff0c;其实也不是很复杂。 曲线的介绍&#xff08;转自维基百科,见…

Bezier曲线原理及其代码实现

Bezier曲线原理及实现代码&#xff08;c&#xff09; 一、原理&#xff1a; 贝塞尔曲线于1962年&#xff0c;由法国工程师皮埃尔?贝塞尔&#xff08;Pierre B?zier&#xff09;所广泛发表&#xff0c;他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由 Paul de Cast…

Bezier曲线及其性质

本文为Bezier曲线mooc教程学习笔记。 目录 Bezier曲线与曲面[1] Bezier曲线的背景[2] Bezier曲线[3] Bezier曲线详细定义[4] Bezier曲线举例[5] Bernstein 基函数性质[6] 贝塞尔曲线的性质[7] Bezier曲线的生成[8] Bezier曲线的拼接[9] Bezier曲线的升阶与降阶 Bezier曲线与曲面…

Bezier曲线原理

一、原理&#xff1a; 贝塞尔曲线于1962年&#xff0c;由法国工程师皮埃尔贝塞尔&#xff08;Pierre Bzier&#xff09;所广泛发表&#xff0c;他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau 于1959年运用de Casteljau 算法开发&#xff0c;以稳…

如何将多张图片合成一个pdf?

如何将多张图片合成一个pdf&#xff1f;平时我们都喜欢将word或者ppt文件转换成pdf后再使用&#xff0c;除此之外&#xff0c;我们还会将多张图片合并转换成pdf文件&#xff0c;大家会用什么方法将图片合并成pdf呢&#xff1f;我相信有很多小伙伴会使用这个方法&#xff0c;先将…

怎么把四个图片合成一个图片?

怎么把四个图片合成一个图片&#xff1f;关于图片的合成&#xff0c;我们一般都会用到图片处理软件来进行。但是对于一些职场新人来说&#xff0c;他根本不会用一些专业的图片处理软件&#xff0c;那么这个问题对他来说就是非常棘手的。其实遇到这样的问题&#xff0c;新人朋友…

python将多张图片合并成一张图片

文章目录 说明&#xff1a;合并图片的三个过程1、参考原博主的&#xff1a;2、优化第一个数量问题&#xff1a;3、优化俩个问题&#xff08;数量不限性状按比例变小&#xff09;4、优化黑行高度问题5、合成图片不清晰问题&#xff1a;总结下&#xff1a; 说明&#xff1a; 今天…

如何把一张图片分割成几张

把一张图片分割成几张的方法&#xff1a; 工具/原料&#xff1a;硬件&#xff1a;电脑、软件&#xff1a;Photoshop 7.0、系统&#xff1a;Windows10专业版64位操作系统。 1、打开平PS&#xff0c;进入新建文档里面&#xff0c;然后把图片直接拉到界面中。或者直接打开图片。 2…

jpg怎么合成一份_如何将多张图片合成一个文件

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 将多张图片合成一个文件的方法是&#xff1a; 1、将所有图片拖到一个文件夹里&#xff0c;鼠标右键点击“添加压缩”。 2、点击确定&#xff0c;这样就成了一个文件。 计算机(compu…

怎样能把两张照片拼成一张图片,5种工具分享

怎样能把两张照片拼成一张图片&#xff1f;图片拼合的应用场景是很多的。比如将几张相册中的照片拼成一张合影、将多个地图截图拼合在一起形成一个更大的区域地图、将多个漫画图像合并成一本漫画册等。这项技术可以方便地将多张图片整合为一张&#xff0c;节省时间和精力。 因此…

怎么将几张照片合成一张图片,简单步骤易学

怎么将几张照片合成一张图片&#xff1f;在当代社会&#xff0c;图片已经成为了人们生活和工作中不可或缺的重要元素。无论是在网上浏览、社交媒体、电商平台、还是在企业营销、科研教育、娱乐创作等各种场合中&#xff0c;都有着广泛的应用。而将不同的图片进行合并&#xff0…

多张图片怎么合成一个pdf?

多张图片怎么合成一个pdf&#xff1f;相信大家和我一样&#xff0c;每天的工作或者生活学习都离不开pdf文件&#xff0c;因为pdf文件拥有更好的稳定性和安全性&#xff0c;不管是在电脑还是在其他设备上&#xff0c;都能正常的打开&#xff0c;而且pdf文件不易编辑的特性&#…

如何把两张图片拼在一起?

如何把两张图片拼在一起&#xff1f;一般来说&#xff0c;如果我们的照片只是简单处理的话&#xff0c;我们在手机上使用一些小软件就能完成&#xff0c;比如我们常使用的秀秀。但是如果说我们需要合成的照片是比较大的&#xff0c;那种专业相机拍出来的像素比较高。这种情况下…

多张图片合成一张jpg工具_如何将两张图片合成一张图片?

您可能感兴趣的话题&#xff1a; 美图秀秀 核心提示&#xff1a;图片叠加的方法也有几种&#xff0c;小编认为最好用、效果最好的是美图秀秀抠图叠加法。 看到许多网友焦急的询问一些图片处理方面的问题&#xff0c;一时又没人给点温馨的帮助&#xff0c;一向助人为乐的小编就坐…

多张图片怎么合成一个pdf文件?

小编作为一个上班族&#xff0c;每天会涉及到很多的图片文件&#xff0c;日积月累图片文件的整理和保存是一个任务艰巨的工作。那么如何更好的管理这些图片文件呢&#xff1f;小编有个好方法就是将有关系的某些图片文件全部整理到一个PDF文件内&#xff0c;这样一个类别的PDF包…

三张图片怎么拼成一张?

三张图片怎么拼成一张图片&#xff1f;相信大家平时都有往朋友圈分享图片的经历&#xff0c;朋友圈的九宫格是大部分人分享日常的常用方式&#xff0c;那如果大家想要分享的照片超过九张&#xff0c;就需要将图片拼接一下再发&#xff0c;这样就可以分享多张照片了。比如我将三…

怎么把多张图片合成为一张?

将多张图片合成为一张图片是在很多场合下都非常有必要的&#xff0c;例如设计制作等。其中&#xff0c;合成图片的关键性和重要性主要包括以下几点&#xff1a;首先&#xff0c;保证合并后的图片质量。在进行多张图片合成时&#xff0c;需要保证图片大小和分辨率的统一&#xf…

Python实现多张图片合成一张马赛克图片

前言 最近有网友私信我&#xff0c;问如何把多张图片合成一张马赛克图片的样子 说是女儿从出生到现在&#xff0c;所有的照片&#xff0c;大概有上百张&#xff0c;所以想使用这些照片合成一张&#xff0c;当做生日礼物 那我们今天就用上次爬表情包的图片来做一次马赛克图片…

两张图片怎样合成一张左右拼图?

相信很多小伙伴的手机和电脑上都储存了一定数量的图片&#xff0c;在使用这些图片的时候&#xff0c;因为一些需要有时候我们要将图片拼在一起使用&#xff0c;数量多的时候我们可以拼成长竖图或者长横图&#xff0c;当然也可以借助拼接软件里面的模板进行自由选择拼接。但是如…

怎么将三张图片合成一张图片?

怎么将三张图片合成一张图片&#xff1f;遇到这个问题&#xff0c;我们其实有很多方法来处理。我们首当其冲想到的是其中最常见的&#xff0c;可以使用我们手机的APP来处理&#xff0c;比如某秀秀等。但是此方法比较适合于尺寸比较小的图片进行合并&#xff0c;如果图片比较大的…