贝塞尔曲线 贝塞尔曲线(The Bézier Curves),是一种在计算机图形学中相当重要的参数曲线(2D,3D的称为曲面)。贝塞尔曲线于1962年,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所发表,他运用贝塞尔曲线来为汽车的主体进行设计。
代码实现其实也非常简单,把公式套过来直接用起来就OK了。这里我以3次曲线为例
以上是核心算法,下面是完整代码:
效果图:
代码实现其实也非常简单,把公式套过来直接用起来就OK了。这里我以3次曲线为例
for (double k = t; k <= 1 + t; k += t) { x = (1 - k) * (1 - k) * (1 - k) * ps[0].getX() + 3 * k * (1 - k) * (1 - k) * ps[1].getX() + 3 * k * k * (1 - k) * ps[2].getX() + k * k * k * ps[3].getX(); y = (1 - k) * (1 - k) * (1 - k) * ps[0].getY() + 3 * k * (1 - k) * (1 - k) * ps[1].getY() + 3 * k * k * (1 - k) * ps[2].getY() + k * k * k * ps[3].getY(); g2.drawOval((int) x, (int) y, 1, 1); }
以上是核心算法,下面是完整代码:
package com.opentcs.customization; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import javax.swing.JFrame; import javax.swing.JPanel; public class BezierDemo extends JPanel implements MouseListener, MouseMotionListener { private static final long serialVersionUID = 1L; private Point2D[] ps; private Ellipse2D.Double[] ellipse; private static final double SIDELENGTH = 8; private int numPoints; private double t = 0.002; public BezierDemo() { numPoints = 0; ps = new Point2D[4]; ellipse = new Ellipse2D.Double[4]; this.addMouseListener(this); this.addMouseMotionListener(this); } @Override protected void paintComponent(Graphics g) { // TODO Auto-generated method stub super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(Color.BLUE); for (int i = 0; i < numPoints; i++) { // 绘制圆点 if (i > 0 && i < (numPoints - 1)) { g2.fill(ellipse[i]); } else { g2.draw(ellipse[i]); } // 绘制点之间的连接线 if (numPoints > 1 && i < (numPoints - 1)) g2.drawLine((int) ps[i].getX(), (int) ps[i].getY(), (int) ps[i + 1].getX(), (int) ps[i + 1].getY()); } if (numPoints == 4) { double x, y; g2.setColor(Color.RED); for (double k = t; k <= 1 + t; k += t) { x = (1 - k) * (1 - k) * (1 - k) * ps[0].getX() + 3 * k * (1 - k) * (1 - k) * ps[1].getX() + 3 * k * k * (1 - k) * ps[2].getX() + k * k * k * ps[3].getX(); y = (1 - k) * (1 - k) * (1 - k) * ps[0].getY() + 3 * k * (1 - k) * (1 - k) * ps[1].getY() + 3 * k * k * (1 - k) * ps[2].getY() + k * k * k * ps[3].getY(); g2.drawOval((int) x, (int) y, 1, 1); } } } @Override public Dimension getPreferredSize() { // TODO Auto-generated method stub return new Dimension(600, 600); } public static void main(String[] agrs) { JFrame f = new JFrame(); BezierDemo t2 = new BezierDemo(); f.add(t2); f.pack(); f.setVisible(true); f.setLocationRelativeTo(null); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub if (numPoints < 4) { double x = e.getX(); double y = e.getY(); ps[numPoints] = new Point2D.Double(x, y); Ellipse2D.Double current = new Ellipse2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH); ellipse[numPoints] = current; numPoints++; repaint(); } } private int flag = -1; @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub if (!find((Point2D) e.getPoint())) flag = -1; } private boolean find(Point2D p) { for (int i = 0; i < numPoints; i++) { if (ellipse[i].contains(p)) { flag = i; return true; } } return false; } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseDragged(MouseEvent e) { // TODO Auto-generated method stub if (flag < 5 && flag >= 0) { double x = e.getX(); double y = e.getY(); ps[flag] = new Point2D.Double(x, y); Ellipse2D.Double current = new Ellipse2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH); ellipse[flag] = current; repaint(); } } @Override public void mouseMoved(MouseEvent e) { // TODO Auto-generated method stub } }
效果图:
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (1)
-
if (numPoints == 3) { double x, y; g2.setColor(Color.RED); for (double k = t; k <= 1 + t; k += t) { double tt = 1 - k; x = Math.pow(tt, 2) * ps[0].getX() + 2 * k * tt * ps[1].getX() + Math.pow(k, 2) * ps[2].getX(); y = Math.pow(tt, 2) * ps[0].getY() + 2 * k * tt * ps[1].getY() + Math.pow(k, 2) * ps[2].getY(); g2.drawOval((int) x, (int) y, 1, 1); } }
二次函数稍微,用Math函数实现,看起来简洁一点。
站点信息
- 文章2300
- 用户1336
- 访客10859735
每日一句
True success inspires others to act.
真正的成功是激励他人行动。
真正的成功是激励他人行动。
语法错误: 意外的令牌“标识符”
全面理解Gradle - 定义Task
Motrix全能下载工具 (支持 BT / 磁力链 / 百度网盘)
谷歌Pixel正在开始起飞?
获取ElementUI Table排序后的数据
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is
亲测!虚拟机VirtualBox安装MAC OS 10.12图文教程
华为手机app闪退重启界面清空log日志问题
android ndk开发之asm/page.h: not found
手机屏幕碎了怎么备份操作?
免ROOT实现模拟点击任意位置
新手必看修改DSDT教程
thinkpad t470p装黑苹果系统10.13.2
新会员