十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
作为一个有只志向的码农,除了知道一些基本的知识够自己努力搬砖以外,还应该get一些更炫酷的技能,用更优雅的姿势进行搬砖;想要实现一些十分炫酷的效果,贝塞尔曲线就必须进行一些研究了;最近一段时间,我对贝塞尔曲线进行了部分的研究,因此就打算写贝塞尔曲线系列的文章来记录自己的研究;
创新互联从2013年开始,是专业互联网技术服务公司,拥有项目成都做网站、成都网站建设网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元内乡做网站,已为上家服务,为内乡各地企业和个人服务,联系电话:13518219792
##规矩我都懂 !##
我明白,必须先上图,要不然大家都没兴趣看下去先看比较简单的,贝塞尔曲线的一阶和二阶的应用
看到二阶的贝塞尔曲线有没有感觉很眼熟,没错,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)全解(三):贝塞尔曲线实现满屏爱心 ]
中讲解最后附上源码:
用贝塞尔曲线画就可以了
Private Type POINTAPI
x As Long
y As Long
End Type
Private Declare Function PolyBezierTo Lib "gdi32.dll " (ByVal hdc As Long, lppt As POINTAPI, ByVal cCount As Long) As Long
Private Sub Form_Paint()
Dim pts(0 To 6) As POINTAPI
'set the coördinates
pts(0).x = 22: pts(0).y = 33
pts(1).x = 66: pts(1).y = 55
pts(2).x = 177: pts(2).y = 88
pts(3).x = 199: pts(3).y = 111
pts(4).x = 299: pts(4).y = 222
pts(5).x = 80: pts(5).y = 333
PolyBezierTo Me.hdc, pts(0), 6
End Sub
平均线 ??是个什么线????求出平均值后话直线吗?
那就lineto好了
Private Type POINTAPI
x As Long
y As Long
End Type
Private Declare Function PolyBezierTo Lib "gdi32.dll " (ByVal hdc As Long, lppt As POINTAPI, ByVal cCount As Long) As Long
Private Sub Form_Paint()
Dim pts(0 To 6) As POINTAPI
Dim pt(0 To 6) As POINTAPI
'set the co?rdinates
pts(0).x = 22: pts(0).y = 33
pts(1).x = 66: pts(1).y = 55
pts(2).x = 177: pts(2).y = 88
pts(3).x = 199: pts(3).y = 111
pts(4).x = 299: pts(4).y = 222
pts(5).x = 80: pts(5).y = 333
For n = 1 To 6
pt(n).x = (pts(n).x + pts(n - 1).x) / 2
pt(n).y = (pts(n).y + pts(n - 1).y) / 2
Next n
PolyBezierTo Me.hdc, pt(0), 6
PolyBezierTo Me.hdc, pts(0), 6
End Sub
Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。
曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。
1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。
贝塞尔曲线为计算机矢量图形学奠定了基础。
它的主要意义在于无论是直线或曲线都能在数学上予以描述。
抛物线的三切线定理:
设P0、P02、P2是一条抛物线上顺序三个不同的点。过P0和P2点的两切线交于P1点,在P02点的切线交P0P1和P2P1于P01和P11,则如下比例成立:
当P0,P2固定,引入参数t,令上述比值为t:(1-t),即有:
t从0变到1,第一、二式就分别表示控制二边形的第一、二条边,它们是两条 一次Bezier曲线 。将一、二式代入第三式得:
依次类推,
由四个控制点定义的三次Bezier曲线P03可被定义为分别由(P0,P1,P2)和(P1,P2,P3)确定的两条二次Bezier曲线的线性组合。
即由 (n+1) 个控制点Pi(i=0,1,...,n)定义的n次Bezier曲线P0n可被定义为分别由 前、后n个控制点 定义的 两条(n-1)次 Bezier曲线P0n-1与P1n-1的线性组合:
由此得到Bezier曲线的递推计算公式:
以下公式中:B(t)为t时间下点的坐标;P0为起点,Pn为终点,Pi为控制点
由 P0 至 P1 的连续点P01,描述的一条线段:
transition-timing-function 规定过渡效果的时间曲线为贝塞尔曲线
transition: all 2s cubic-bezier( p1x, p1y, p2x, p2y )
项目预览地址:
用Circle 画圆 圆弧 椭圆 都可以
具体参照下面的详细说明
Circle(1000,1000),500,8,-6,-3
1000,1000,圆心坐标
500,半径
后面分别代表起始角,终止角,长短轴比率
好吧,详细点,就把Circle方法都说一遍
在对象上画圆、椭圆或弧。
语法
object.Circle [Step] (x, y), radius, [color, start, end, aspect]
Circle 方法的语法有如下的对象限定符和部分:
部分 描述
object 可选的。 对象表达式,其值为“应用于”列表中的对象。如果object 省略,具有焦点的窗体作为object。
Step 可选的。关键字 ,指定圆、椭圆或弧的中心,它们相对于当前 object 的 CurrentX 和 CurrentY 属性提供的坐标。
(x, y) 必需的。 Single (单精度浮点数),圆、椭圆或弧的中心坐标。object 的 ScaleMode 属性决定了使用的度量单位。
radius 必需的。Single (单精度浮点数),圆、椭圆或弧的半径。 object 的 ScaleMode 属性决定了使用的度量单位。
color 可选的。Long (长整型数),圆的轮廓的 RGB 颜色。如果它被省略,则使用 ForeColor 属性值。可用 RGB 函数或 QBColor 函数指定颜色。
start, end 可选的。 Single (单精度浮点数),当弧、或部分圆或椭圆画完以后,start 和 end 指定(以弧度为单位)弧的起点和终点位置。其范围从 -2 pi 到 2 pi 。起点的缺省值是0; 终点的缺省值是2 * pi。
aspect 可选的。 Single (单精度浮点数),圆的纵横尺寸比。缺省值为 1.0,它在如何屏幕上都产生一个标准圆(非椭圆)。
说明
想要填充圆,使用圆或椭圆所属对象的 FillColor 和 FillStyle 属性。只有封闭的图形才能填充。封闭图形包括圆、椭圆、或扇形。
画部分圆或椭圆时,如果 start 为负,Circle 画一半径到 start,并将角度处理为正的;如果 end 为负,Circle 画一半径到 end,并将角度处理为正的。Circle 方法总是逆时针(正)方向绘图。
画圆、椭圆或弧时线段的粗细取决于 DrawWidth 属性值。在背景上画圆的方法取决于 DrawMode 和 DrawStyle 属性值。
画角度为 0 的扇形时,要画出一条半径(向右画一水平线段),这时给 start 规定一很小的负值,不要给 0。
.可以省略语法中间的某个参数,但不能省略分隔参数的逗号。您指定的最后一个参数后面的逗号是可以省略的。
Circle 执行时,CurrentX 和 CurrentY 属性被参数设置为中心点。
这个方法不能用在 With匛nd With 语句块中。
--------------------------------------------------------------------------------
Circle 方法示例
这个示例用Circle 方法在窗体中央画许多同心圆。要运行这个示例,将此代码放入窗体的 General 部分。按 F5 并单击窗体。
Sub Form_Click ()
Dim CX, CY, Radius, Limit ' Declare variable.
ScaleMode = 3 ' 以像素为单位。
CX = ScaleWidth / 2 ' X 位置。
CY = ScaleHeight / 2 ' Y 位置。
If CX CY Then Limit = CY Else Limit = CX
For Radius = 0 To Limit ' 半径。
Circle (CX, CY), Radius,RGB(Rnd * 255, Rnd * 255, Rnd * 255)
Next Radius
End Sub
--------------------------------------------------------------------------------
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*)
Line,Circle,Pset,Cls.
辅助命令:RGB,QBColor.
API中绘图命令相当多。
1.设定图素
SetPixel
GetPixel
2.画线
LineTo 画直线。
Polyline和PolylineTo 画一系列相连的直线。
PolyPolyline 画多组相连的线。
Arc 画椭圆线。
PolyBezier和PolyBezierTo 画贝塞尔曲线。
ArcTo和AngleArc 画椭圆线。
PolyDraw 画一系列相连的线以及贝塞尔曲线
3.既画线也填入所画图形的封闭区域的函数,边界框函数
Rectangle 画矩形。
Ellipse 画椭圆。
RoundRect 画带圆角的矩形。
Pie 画椭圆的一部分,使其看起来像一个扇形。
Chord 画椭圆的一部分,以呈弓形。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SetPixel函数在指定的x和y坐标以特定的颜色设定图素:
SetPixel (hdc, x, y, crColor) ;
如同在任何绘图函数中一样,第一个参数是设备内容的句柄。第二个和第三个参数指明了坐标位置。通常要获得窗口显示区域的设备内容,并且x和y相对于该显示区域的左上角。最后一个参数是COLORREF型态指定了颜色。如果在函数中指定的颜色视讯显示器不支持,则函数将图素设定为最接近的纯色并从函数传回该值。
GetPixel函数传回指定坐标处的图素颜色:
crColor = GetPixel (hdc, x, y) ;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
画一条直线,必须呼叫两个函数。第一个函数指定了线的开始点,第二个函数指定了线的终点:
MoveToEx (hdc, xBeg, yBeg, NULL) ;
LineTo (hdc, xEnd, yEnd) ;
MoveToEx实际上不会画线,它只是设定了设备内容的「目前位置」属性。然后LineTo函数从目前的位置到它所指定的点画一条直线。目前位置只是用于其它几个GDI函数的开始点。在内定的设备内容中,目前位置最初设定在点
(0,0).如果在呼叫LineTo之前没有设定目前位置,那么它将从显示区域的左上角开始画线。
当您要将数组中的点连接成线时,使用Polyline函数要简单得多
Polyline (hdc, apt, 5) ;
最后一个参数是点的数目。我们还可以使用(sizeof (apt) / sizeof (POINT))来表示这个值。Polyline与一个MoveToEx函数后面加几个LineTo函数的效果相同,但是,Polyline既不使用也不改变目前位置。PolylineTo有些不同,这个函数使用目前位置作为开始点,并将目前位置设定为最后一根线的终点
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Rectangle (hdc, xLeft, yTop, xRight, yBottom) ;
点(xLeft, yTop)是矩形的左上角,(xRight, yBottom)是矩形的右下角。用函数Rectangle画出的图形如图5-6所示,矩形的边总是平行于显示器的水平和垂直边