现在想用三次贝塞尔曲线模拟一个悬链式方程(方程已知),因为一段三次贝塞尔曲线需要四个控制点
,现在知道起点P0和终点P3,可以根据方程式计算出曲线上若干点的坐标,怎么根据这些点计算出贝塞尔曲线上另外两个控制点P1,P2的坐标。另外,横坐标轴和纵坐标轴的比例不一样,是否需要对计算后的点进行转换
,现在知道起点P0和终点P3,可以根据方程式计算出曲线上若干点的坐标,怎么根据这些点计算出贝塞尔曲线上另外两个控制点P1,P2的坐标。另外,横坐标轴和纵坐标轴的比例不一样,是否需要对计算后的点进行转换
解决方案 »
- winsock问题,连带二进制数据转换。这几天搞得人都要晕过去了。
- 数据库与combo控件的问题
- 请高手指点如何在ListView中用checkbox显示和修改的问题!!!问题解决分不够可以另加
- 急问:有关将SQL数据导出到WORd表中
- vb里一切正常,编译成EXE后运行后关闭退出时报错,这是为什么?内有出错信息
- vb中打印报表能否打印出毕业证书这样的格式?
- 关于mscomm的问题!
- 请教高手:DrawAnimatedRects API怎样实现拨号成功后窗口收缩到托盘上的动画效果?
- 如何让Textbox在得到光标的同时,按下Enter键才响应一个事件???
- datareport报表中image图象框的问题
- 有关VB6.0中msgbox的函数
- 连接
'说明:
' 该模块用于在指定
'函数形式:
' Bezier(Obj , X() , Y() , PenStyle , Width , Color)
'参数说明
' obj: 对象名,一个picture 控件的完整名,如 form1.pic1
' x(): 关键点的x坐表数组
' y(): 关键点的y坐表数组
' PenStyle: 画笔的式样 可以定义以下值
' 0 画出的是实线 _________
' 1 画出的是虚线 _ _ _ _ _ (Width必须是1)
' 2 画出的是点线 .......... (Width必须是1)
' 3 画出的是点划线 ._._._._._ (Width必须是1)
' 4 画出的是点-点-划线 .._.._.._..(Width必须是1)
' 5 不能画图
' width: 线的宽度,当不是1的时候 penstyle 无效
' color: 线的颜色,可以用RGB()函数定义Public Declare Function CreatePen& Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long)
Public Declare Function DeleteObject& Lib "gdi32" (ByVal hObject As Long)
Public Declare Function SelectObject& Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long)
Public Const PS_SOLID& = 0 '实线
Private Declare Function PolyBezier& Lib "gdi32" (ByVal hdc As Long, lppt As POINTAPI, ByVal cPoints As Long)
'描绘贝塞尔(Bezier)曲线。Private Type POINTAPI '关键点坐标结构
X As Long '点的x坐标
Y As Long '点的y坐标
End Type
Dim Points() As POINTAPI
Dim ptNum As Integer '点的数量
Sub Bezier(Obj As Object, X() As Long, Y() As Long, ByVal PenStyle As Long, ByVal Width As Long, ByVal Color As Long) For i = LBound(X) To UBound(Y) '
AddPoints X(i), Y(i) '添加数据点
Next ' DrawBezier Obj, PenStyle, Width, Color '绘制贝塞尔曲线
DrawBezier Obj, PenStyle, Width, ColorReDim Points(0): ptNum = 0
End Sub
Sub DrawBezier(Obj As Object, ByVal PenStyle As Long, ByVal Width As Long, ByVal Color As Long)
Dim i As Integer
Dim iCount As Integer
NewPen& = CreatePen(PenStyle, Width, Color)
OldPen& = SelectObject(Obj.hdc, NewPen&)
iCount = 0
For i = 1 To ptNum - 2
iCount = iCount + 1
If iCount = 4 And i >= 4 Then
Obj.ForeColor = vbWhite
PolyBezier Obj.hdc, Points(i - 3), 4
iCount = 1
End If
Next
SelectObject Obj.hdc, OldPen&
DeleteObject NewPen&
End SubSub AddPoints(X As Long, Y As Long)
'增加关键点
Dim Line1 As Double
Dim Line2 As Double
Dim Line3 As Double
Dim X1 As Double
Dim x2 As Double
Dim Y1 As Double
Dim y2 As Double
Dim b As Double
ReDim Preserve Points(ptNum + 2)
If (ptNum + 3) / 3 >= 2 Then
Points(ptNum).X = X - (X - Points(ptNum - 2).X) / 3
Points(ptNum - 1).X = Points(ptNum - 2).X + (X - Points(ptNum - 2).X) / 3
End If
Points(ptNum).Y = Y
If (ptNum + 3) / 3 >= 3 Then
Line1 = (Points(ptNum - 2).Y - Y) / (Points(ptNum - 2).X - X)
Line2 = (Points(ptNum - 2).Y - Points(ptNum - 5).Y) / (Points(ptNum - 2).X - Points(ptNum - 5).X)
X1 = 1000 * Cos(Atn(Line1))
Y1 = 1000 * Sin(Atn(Line1))
x2 = 1000 * Cos(Atn(Line2))
y2 = 1000 * Sin(Atn(Line2))
Line3 = (x2 - X1) / (Y1 - y2)
b = Points(ptNum - 2).Y - Line3 * Points(ptNum - 2).X
Points(ptNum - 3).Y = Line3 * Points(ptNum - 3).X + b
Points(ptNum - 1).Y = Line3 * Points(ptNum - 1).X + b
End If
Points(ptNum + 1).X = X
Points(ptNum + 1).Y = Y
Points(ptNum + 2).X = X
Points(ptNum + 2).Y = Y
ptNum = ptNum + 3 '每次确定三个点,三个点的位置一样,中间一个为起点
'或终点,其余两个用于控制End Sub
调用举例 Dim a(10) As Long
Dim b(10) As Long
For i = 1 To 10
Randomize
a(i) = i * 50
b(i) = i * 50 * Rnd
Next
Style = 0
Bezier Form1.Picture1, a, b, Style, 1, RGB(255, 0, 0)
Line3 = (x2 - X1) / (Y1 - y2)
b = Points(ptNum - 2).Y - Line3 * Points(ptNum - 2).X
Points(ptNum - 3).Y = Line3 * Points(ptNum - 3).X + b
Points(ptNum - 1).Y = Line3 * Points(ptNum - 1).X + b
我认为将Line3 = (x2 - X1) / (Y1 - y2)修改为Line3 = (Y1 - y2)/(x2 - X1)可能还好理解一点,还有一个问题:
X1 = 1000 * Cos(Atn(Line1))
Y1 = 1000 * Sin(Atn(Line1))
x2 = 1000 * Cos(Atn(Line2))
y2 = 1000 * Sin(Atn(Line2))
中的1000有什么根据,为什么要乘以该系数