关于java画bezier的信息
今天给各位分享java画bezier的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、史上最全的贝塞尔曲线(Bezier)全解(一):初识贝塞尔曲线
- 2、怎么求 Java 贝塞尔曲线两点之间的角度
- 3、如何实现任意阶次bezier曲线的生成
- 4、画一条贝塞尔曲线!!
- 5、三次Bezier曲线绘制编程
- 6、3dmax里怎么画bezier曲线?。。
史上最全的贝塞尔曲线(Bezier)全解(一):初识贝塞尔曲线
作为一个有只志向的码农,除了知道一些基本的知识够自己努力搬砖以外,还应该get一些更炫酷的技能,用更优雅的姿势进行搬砖;想要实现一些十分炫酷的效果,贝塞尔曲线就必须进行一些研究了;最近一段时间,我对贝塞尔曲线进行了部分的研究,因此就打算写贝塞尔曲线系列的文章来记录自己的研究;
##规矩我都懂 !##
我明白,必须先上图,要不然大家都没兴趣看下去先看比较简单的,贝塞尔曲线的一阶和二阶的应用
看到二阶的贝塞尔曲线有没有感觉很眼熟,没错,360的下火箭弹射时候的小弹弓,还有滑动控件的阴影提示;以前的时候很多小伙伴跟我说这要计算多少数据啊,完全没办法实现啊,现在有了贝塞尔曲线,可以很简单的实现这一个功能;
不过完全不能这样满足啊,接下来还有更复杂一些的曲线 没错,这个就是三阶的使用,有没有感觉路线更加复杂,不过还好,使用贝塞尔去玩完全可以轻松实现;对了,还有一个心在沿着曲线移动,看到这里,小伙伴们肯定会想到满屏幕的心在飞的场景,放心,这个我也实现了,在接下来的文章里,我会一一进行讲解
##图片看完了,现在简单了解贝塞尔曲线 ##
Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。以下公式中:B(t)为t时间下 点的坐标;P0为起点,Pn为终点,Pi为控制点一阶贝塞尔曲线(线段):
意义:由 P0 至 P1 的连续点, 描述的一条线段二阶贝塞尔曲线(抛物线):
原理:由 P0 至 P1 的连续点 Q0,描述一条线段。由 P1 至 P2 的连续点 Q1,描述一条线段。由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。经验:P1-P0为曲线在P0处的切线。
三阶贝塞尔曲线:
通用公式:
利用贝塞尔曲线的这些特性,我们可以画出很多炫酷的曲线,所以贝塞尔曲线还是值得我们去研究学习的;##但是这些完全记不住啊!!! ##没关系,可以很负责的说,我也是!!!!!上面的曲线完全是来自[ ] 所以,如果你的数学和我一样是体育老师教的,就忘记这些吧,跟我一起看看android中是实现一条贝塞尔曲线的,android已经帮我们实现好了,剩下的就需要我们进行简单使用,具体的使用,就看
[ 史上最全的贝塞尔曲线(Bezier)全解(二):Android中曲线的简单绘制 ]
[ 史上最全的贝塞尔曲线(Bezier)全解(三):贝塞尔曲线实现满屏爱心 ]
中讲解最后附上源码:
怎么求 Java 贝塞尔曲线两点之间的角度
public void test() {
CvPoint controlPoint[] = new CvPoint[4];
controlPoint[0] = new CvPoint(50, 60); //起点
controlPoint[1] = new CvPoint(130, 200); //控制点
controlPoint[2] = new CvPoint(300, 360); //控制点
controlPoint[3] = new CvPoint(400, 600); //终点
int n = controlPoint.length - 1; //
int i, r;
float u;
bezierPoint.clear();
// u的步长决定了曲线点的精度
for (u = 0; u = 1; u += 0.01) {
CvPoint p[] = new CvPoint[n + 1];
for (i = 0; i = n; i++) {
p[i] = new CvPoint(controlPoint[i].x, controlPoint[i].y);
}
for (r = 1; r = n; r++) {
for (i = 0; i = n - r; i++) {
p[i].x = (1 - u) * p[i].x + u * p[i + 1].x;
p[i].y = (1 - u) * p[i].y + u * p[i + 1].y;
}
}
bezierPoint.add(p[0]);
}
for (CvPoint point : bezierPoint) {
System.out.println(point.x + "," + point.y);
}
}
如何实现任意阶次bezier曲线的生成
如何利用VC + + 编程技术在图形系统中动态绘制任意阶Bezier 工程曲线方 法,并且使绘制的曲线具有捕捉、修改、动态增加型值点等功能。利用同样的方法,可以实现 B 样条、三次参数等其它工程曲线的绘制,从而扩大了Bezier 等曲线的工程应用。 关键词:Bezier 曲线; 动态绘制; 高阶; VC + + 中图分类号: TP391 文献标识码:A 文章编号:1671 - 5322(2004) 04 - 0029 - 05 UG、CATIA 等图形系统可以实现B 样条曲线 的动态绘制方法,但没有Bezier 、三次参数样条等 曲线的绘制方法。虽然B 样条曲线使用最广泛, 但Bezier 、三次参数样条在工程上也有较多的运 用。为拓宽工程曲线的应用范围, 在结合现行 Bezier 等曲线的算法的基础上,利用VC + + 开发 工具实现了高阶Bezier 等曲线的绘制方法,较方 便地动态实现了曲线的修改。本设计模块可以单 独使用,也可作为一个模块嵌入其它图形系统中 使用。从绘制Bezier 曲线的方法中可了解用现行 绘图软件实现曲线的动态绘制、曲线的识别、拖动 型值点修改曲线等编程方法,该方法对于开发其 它专业图形系统有极大的帮助。 1 Bezier 曲线的算法 1. 1 Bezier 曲线的描述 设 P 0 , P 1 , P 2 , …, P n , 为 n 阶Bezier 曲线的特 征多边形控制点,则Bezier 曲线一般表达式为 P( t) = ∑ n i =0 B i , n ( t) P i , 0 ≤t ≤1 (1) 其中: B i , n ( t) = C n i (1 - t) n - i t i ( i = 0 , 1 , …n) 1. 2 绘制Bezier 曲线的条件 绘制Bezier 曲线的条件有两种,一是给出型 值点坐标,另一是给出控制点坐标。在计算中,一 般最终是利用控制点坐标计算来绘制曲线的。当 给出的数据是型值点时,要利用型值点的坐标值 反求出控制点坐标,再利用控制点坐标进行插补 运算求出曲线的坐标,反求控制点的算法为: 设给出的型值点为 Q 0 , Q 1 , Q 2 …Q n , 要反求 的控制点为 P 0 , P 1 , P 2 …P n , 设参数 t = 0 , 1/ n , 2/ n …1 时分别经过 Q 0 , Q 1 , Q 2 …Q n , 根据Bezier 定义有 Q 0 = P(0) = P 0 Q 1 = P(1/ n) = B 0 , n (1/ n) P 0 + B 1 , n (1/ n) P 1 + … + B n , n (1/ n) P n …… (2) Q n- 1 = P( ( n - 1) / n) = B 0 , n ( ( n - 1) / n) P 0 + B 1 , n ( ( n - 1) / n) P 1 + …+ B n , n P n Q n = P n 把上式写成矩阵形式,利用矩阵的求逆运算, 求出控制点为式(3) 。
2 绘制曲线类的方法 2. 1 构造Bezier 曲线类 在VC + + 中绘制Bezier 曲线,首先建立Bezi2 er 曲线类,利用Bezier 类的指针来对Bezier 曲线进 行控制。在VC + + 中所构造Bezier 的曲线类为 CBezier : : CBezier ( short ColorPen , short Color2 Brush , float LineWide , short LineType , float x- Scale , short Layer , int id-only , bool Delete , BpointStruct 3 BpointList) : CDraw ( ColorPen , ColorBrush ,LineWide , LineType ,x- Scale ,Layer ,id-only ,Delete) 各参数的控制对象分别为线型、颜色、线宽、 比例、图层、曲线 ID 号、删除状态、型值点数目、存 放型值点的结构指针,其中BpointStruct 结构有 x 和y 两个成员, 存放型值点坐标, CDraw 类为 CBezie 的基类,该类的各个参数在构造成时完成 初始化。CBezier 类成员有: int m-Numble ;/ / 存放结点的数目 BPointStruct 3 m-BpointList ;/ / 存放型值点的坐 标 BPointStruct 3 m- CpointList ;/ / 存放反求的控制 点的坐标 void Draw ( CDC 3 pDC , int m-DrawMode , int m- DrawMode1 ,short BackColor) ;/ / 绘制曲线函数 BOOL IsPoint (float x ,float y ,float jl ,float blc ,int 3 No) ; / / 判断曲线是否选中函数 virtual void MDpoint ( int num , float x , float y) ;/ / 修改控制点函数 void GetRect (float 3 minX,float 3 minY,float 3 maxX, float 3 maxY) ;获得曲线区域函数 virtual~CBezier () ;/ / CBezier 的析函数 CBezier 类成员在类构造时完成参数数值的 传递,绘制曲线时构造一个CBezier 类对象。为了 存储构造的对象指针,在文档类中建立一个存放 曲线指针的指针m-BezierArray。 CTypedPtrArray CObArray , CBezier 3 m- BezierArray。 2. 2 动态绘制Bezier 曲线 Bezier 曲线类由Draw 函数完成曲线的绘制, 在Draw中完成曲线的反求控制点、插补运算、区 域的计算, 设置线型、颜色、线宽等功能。Bezier 曲线的绘制方法是当用户选择绘制 Bezier 曲线的 功能时,用户在屏幕上拾取型值点时或输入型值 点坐标,在屏幕上动态绘制曲线,绘制中每增加一 个型值点时,则Bezier 曲线的阶次增加一阶,此方 法可以实现任意阶的Bezier 曲线的绘制, 这和B 样条的曲线绘制方法不同,B 样条曲线可用多个 三次B 样条曲线绘制N 个型值点样条曲线,得到 的曲线是光滑连续的,而Bezier 曲线随着型值点 个数的增加,若用升阶的方法计算,则绘制程序要 根据型值点的个数重新计算曲线的坐标。Draw 函数绘制的程序流程如图1 所示。 图1 Draw函数的流程图 Fig. 1 Process flowfor drawfunction 在程序中构造成计算矩阵时,把与坐标值对 应的参数 t 的值代入伯恩斯坦基函数计算出与各 型值点对应的各个基函数值,其中调用了求阶乘、 求幂等函数,然后组合成一个基函数矩阵,再调用 矩阵的求逆运算,本模块中采用全选主元高斯消 �9�9 0 3 �9�9 盐城工学院学报(自然科学版) 第17 卷 去法进行求逆,得到计算的系数矩阵,求出控制点 坐标,根据Bezier 曲线的计算公式计算出曲线的 坐标。绘制Bezier 曲线调用了CDC类的绘制直线 方法,用直线段来近似代替曲线,图形系统中绘制 曲线大多采用这种方法,曲线的近似程度和所采 用的插值间距有关。为了得到好的显示效果,要 把间距控制视觉能接受的范围内。由于无论曲线 多长, t 的值都是在0~1 之间, 当 t 的分隔间距恒 定时, 在动态绘制过中, 随着曲线长度的增加, 直 线的逼近效果越差。t 的划分方法很多, 可以利 用等间距、等弦长方法来解决这一问题, 一般来 说, t 的插值间距为非均匀, 而让每一段代替曲线 的直线段的距离为定值, 获得好的视觉效果。 2. 3 增加Bezier 曲线 在动态绘制过程中,当鼠标移动过程中,曲线 也随着鼠标的位置不同实现重画。这时的图形指 针并没有存储到Bezier 曲线类的m-BezierArray 数 组中。只有当完成曲线绘制时,发出命令后才进 行曲线的最后绘制,对象指针才加入到 m-Bezier2 Array 中存储。当用鼠标的右键结束绘制时,在鼠 标的消息函数中增加以下语句 pDoc AddCBezier ( m-pColor , m- brColor , m- LineWide ,m-LineType ,m-xScale ,m-Layer ,id-only ,0 , PushNumb ,BPointXyz) - Draw( ddd ,0 ,1 ,m- bCol2 or) ; AddCBezier 函数在文档类中定义, 它完成对 象的增加,存储指针。得到指针后,调用Draw 函 数绘制直线。 3 实现曲线类动态修改 3. 1 曲线的捕捉 曲线的捕捉功能是图形系统的基本功能,要 实现曲线的捕捉前提是获得曲线类的对象指针, 建立Bezier 曲线类的目的就是为了实现曲线的捕 捉、移动、修改、删除、恢复, 移动和缩放功能。 Bezier 类中 IsPoint 函数就是为了实现鼠标移动过 程中鼠标位置与曲线之间距离的计算,距离判别 最简单的方法是计算鼠标点位置和对象中的存储 的型值点距离,若距离在设定的范围内,则把选中 的图形突出显示。IsPoint 函数不但返回曲线是否 选中的逻辑值,而且利用参数返回选中曲线的型 值点的序号。更为复杂的方法是把鼠标点和曲线 的坐标进行判别,这种判别方法可用的判别点多, 曲线易选中,但计算复杂,系统采用第一种方法实 现捕捉功能。 3. 2 曲线的修改 在绘图过程中,有时需要修改图形,一般是通 过修改型值或控制点的位置来达到所要求的曲线 形状。为了修改型值或控制点,在Bezier 类中增 加了Mdpoint 函数, 在函数中根据 IsPoint 返回的 型值点或控制点的序号替换它们的坐标,然后重 画曲线,这样就实现了动态修改的功能。 3. 3 曲线的删除、恢复 曲线删除有两种情况,一种是可以恢复的,另 一种是不可恢复的。不可恢复的的删除,只要在 存放对象指针的m-BezierArray 数组中删除所要删 除的曲线指针。如果是可恢复的删除,只是在对 象的成员中增加了删除标志,在重画曲线时,做了 删除标志的曲线不绘制,而对象指针并没有从指 针数组中删除。 3. 4 曲线的移动和缩放 曲线移动是让曲线做平移。平移时,根据平 移的 X, Y方向的距离在曲线的型值或控制点上 加上一个平移值,该值的正负号表示移动方向。 曲线的缩放是根据图形的缩放比例对图形放 大或缩小。在程序中,增加了缩放的比例因子和 从逻辑坐标到实际坐标转换函数VPtoDP 以及从 实际坐标到逻辑坐标的转换函数DPtoVP ,在坐标 转换函数中,通过缩放的比例因子改变坐标值达 到缩放目的。VPtoDP 函数定义如下 void CVDrawView: : DPtoVP (float x ,float y , int 3 X,int 3 Y) { 3 X= (int) ( (x - m-xStart) / blc) ; if (m-MapMode = = 1) 3 Y= m- hScreen - (int) ( (y - m-yStart) / blc) ; else 3 Y= (int) ( (y - m-yStart) / blc) - m- hScreen ; } 其中,blc 就是坐标变换中的缩放因子,m-xS2 tart 、m-yStart 是调节整个图形的平行移动坐标。 4 实现曲线动态绘制的过程 在实现Bezier 曲线的绘制过程中,绘制过程 会调用了许多函数,利用了鼠标的消息函数来实 现绘图操作。具体实现的过程是先用鼠标单击左 键在屏幕上拾取曲线的型值点,当拖动鼠标时,曲 线随着鼠标的移动在不断的变化。
画一条贝塞尔曲线!!
void CBSplineView::bezier(CPoint *pp, int n)
{//画Bezier曲线
int x,y,i,j,k=100;
double t,t1,u,v;
double temp,temp1,temp2,bi;
CClientDC dc(this);
OnPrepareDC(dc);
t=1.0/k;
dc.MoveTo(pp[0]);
for(j=1;jk;j++)
{
t1=j*t;
u=t1;
v=1-u;
x=0;
y=0;
for(i=0;i=n;i++)
{
temp=double(fac(n)/fac(i)/fac(n-i));
temp1=powi(u,i);
temp2=powi(v,n-i);
bi=temp*temp1*temp2;
x=x+bi*pp[i].x;
y=y+bi*pp[i].y;
}
dc.LineTo(x,y);
}
dc.LineTo(pp[n]);
}
long CBSplineView::fac(int m)
{//求m的阶乘
int i;
long temp=1;
if(m==0)
return 1;
else
{
for(i=2;i=m;i++)
temp*=i;
}
return temp;
}
double CBSplineView::powi(double v, int k)
{//求解v的k次幂
double temp=1.0;
if(k==0||v==0)
return 1;
else
{
for(int i=1;i=k;i++)
temp*=v;
}
return temp;
}
曲线通过关键点控制,可以通过选取关键点并拖拽来改变曲线。
mouse点击的HitTest:
通用方法:
用描画的方法把Bezier画在MemoryDC里, 得到测试点的像素值,以判断是否在线上.
(通过剪裁区来减少描画范围)
应该是这样吧!(*n_ n*)
三次Bezier曲线绘制编程
顺便练一下贝塞尔函数,写了一个applet,每秒钟随机生成4个点展示效果。
满足题目要求的接口。
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class Test extends Applet {
private static final long serialVersionUID=-1570645570118871214L;
private int px[],py[];
private Random rnd;
@Override
public void init(){
rnd=new Random(System.currentTimeMillis());
px=new int[4];
py=new int[4];
Timer t=new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
repaint();
}
}, 0, 1000);
}
private void generate(){
for(int i=0;i4;i++){
px[i]=rnd.nextInt(150);
py[i]=rnd.nextInt(150);
}
}
static public void drawBezier(
Graphics g,
int x0,int y0,
int x1,int y1,
int x2,int y2,
int x3,int y3){
int
px[]={x0,x1,x2,x3},
py[]={y0,y1,y2,y3};
g.setColor(Color.RED);
for(int i=0;ipx.length;i++){
g.fillOval(px[i], py[i], 5, 5);
}
g.setColor(Color.GREEN);
double x=0,y=0;
int c=0;
for(double t=0;t=1;t+=0.01){
double dx=cubicBezier(t, px),
dy=cubicBezier(t,py);
System.out.println("dx:"+dx+", dy:"+dy);
if(c++0) g.drawLine((int)x, (int)y, (int)dx, (int)dy);
x=dx; y=dy;
}
}
static private double cubicBezier(double t,int p[]){
return Math.pow(1-t,3)*p[0]+
3*t*Math.pow(1-t,2)*p[1]+
3*Math.pow(t,2)*(1-t)*p[2]+
Math.pow(t,3)*p[3];
}
@Override
public void paint(Graphics g){
generate();
drawBezier(g,
px[0],py[0],
px[1],py[1],
px[2],py[2],
px[3],py[3]
);
}
}
3dmax里怎么画bezier曲线?。。
1、首先定义bernstein基函数,用于计算在给定t点列的对应的bernstein基函数的值。3次bezier曲线为例。
2、给出控制顶点的的xy坐标。
3、定义参数t的点列,定义xx和yy为0,分别存储计算得到的bezier曲线对应的x坐标和y坐标的值。
4、计算bezier曲线在对应点列的值。根据bezier曲线的公式。
5、画出bezier曲线和对应的控制多边形、控制顶点。
6、绘制出的函数图像效果。
关于java画bezier和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。