呵呵,弄成椭圆的了,抱歉抱歉! 同意8楼,实质可由圆的参数方程: x = r * Cos(n) y = r * Sin(n) 推得
据说可以用向量的旋转来解决此问题,我根据BCB的代码转换过来,好像还不行 ' ' #define PI 3.14159265 ' ' void DrawLineArrow(TCanvas* Canvas, TPoint p0, TPoint p1) ' { ' //对于点(x0,y0)指向(x1,y1)的箭头线,以(x1,y1)为原点,先计算出(x1,y1) ' //指向(x0,y0)的单位向量,箭头线与直线的角度为d,那么就是将这个向量 ' //旋转角度d和-d,向量旋转的公式为: ' //(a+b*i)*(cos(d)+i*sin(d)) = a*cos(d)-b*sin(d) + i*(a*sin(d)+b*cos(d)) ' //因为上面的向量以(x1,y1)为原点的单位向量,所以还需要乘以一个长度( ' //箭头线的长度),然后加上偏移就可以了。也就是画的箭头线的顶点的坐标为 ' //x=x1+L*(a*cos(d)-b*sin(d)), y=y1+L*(a*sin(d)+b*cos(d))。 ' //另一个顶点的坐标,将上面的sin(d)换成 -sin(d) 就可以了。 ' //上面公式中的a为(x0-x1)/L0, b为(y0-y1)/L0,L0是(x0,y0)与(x1,y1)的长度, ' //L是箭头线的长度(自己设定)。 ' float a, b, L0, L, d, x, y; ' ' Canvas->MoveTo(p0.x, p0.y); ' Canvas->LineTo(p1.x, p1.y); //画p0 到 p1 的直线 ' ' L0 = sqrt(pow(p0.x-p1.x,2)+pow(p0.y-p1.y,2)); //直线的长度 ' a = (p0.x-p1.x)/L0; b = (p0.y-p1.y)/L0; //单位向量的两个分量 ' L = 10.0; //箭头线长度,这儿我写成固定的,你可以自己修改或者计算 ' d = 30.0/180.0*PI; //箭头线与直线的角度30度,你可以自己调整 ' for(int n=0; n<2; n++) { ' x = p1.x+L*(a*cos(d)-b*sin(n==0?d:-d)); ' y = p1.y+L*(a*sin(n==0?d:-d)+b*cos(d)); ' Canvas->MoveTo(p1.x, p1.y); ' Canvas->LineTo(x, y); //画箭头线 ' } ' }Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long Private Declare Function MoveTo Lib "gdi32" Alias "MoveToEx" ( _ ByVal hdc As Long, ByVal x As Long, ByVal y As Long, _ Optional lpPoint As Any = 0) As Long
Private Type POINTAPI x As Long y As Long End TypePrivate Const PI = 3.14159265358979Private Sub DrawLineArrow(TCanvas As PictureBox, p0 As POINTAPI, p1 As POINTAPI)Dim a%, b%, L0%, L%, d%, x%, y% Dim n As Integer MoveTo TCanvas.hdc, p0.x, p0.y '画p0 到 p1 的直线 LineTo TCanvas.hdc, p1.x, p1.y
'直线的长度 L0 = Sqr((p1.x - p0.x) ^ 2 + (p1.y - p0.y) ^ 2) '单位向量的两个分量 a = (p0.x - p1.x) / L0 b = (p0.y - p1.y) / L0 '箭头线长度10 L = 10 '箭头线与直线的角度30度 d = 30 / 180 * PI
n = 0 x = p1.x * L * (a * Cos(d) - b * Sin(IIf(n = 0, d, -d))) y = p1.y * L * (a * Sin(IIf(n = 0, d, -d) + b * Cos(d))) MoveTo TCanvas.hdc, p1.x, p1.y '画箭头线 LineTo TCanvas.hdc, x, y
n = 1 x = p1.x * L * (a * Cos(d) - b * Sin(IIf(n = 0, d, -d))) y = p1.y * L * (a * Sin(IIf(n = 0, d, -d) + b * Cos(d))) MoveTo TCanvas.hdc, p1.x, p1.y '画箭头线 LineTo TCanvas.hdc, x, y
n = 2 x = p1.x * L * (a * Cos(d) - b * Sin(IIf(n = 0, d, -d))) y = p1.y * L * (a * Sin(IIf(n = 0, d, -d) + b * Cos(d))) MoveTo TCanvas.hdc, p1.x, p1.y '画箭头线 LineTo TCanvas.hdc, x, y
End Sub Private Sub Command1_Click() Dim p0 As POINTAPI, p1 As POINTAPI p0.x = 10: p0.y = 10 p1.x = 120: p1.y = 130
DrawLineArrow Picture1, p0, p1End Sub
Option ExplicitPrivate Type POINTAPI X As Long Y As LongEnd TypePrivate Const ALTERNATE = 1 Private Const BLACK_BRUSH = 4Private Declare Function Polygon _ Lib "gdi32" (ByVal hdc As Long, _ lpPoint As POINTAPI, _ ByVal nCount As Long) As Long Private Declare Function GetStockObject Lib "gdi32" (ByVal nIndex As Long) As Long Private Declare Function CreatePolygonRgn _ Lib "gdi32" (lpPoint As Any, _ ByVal nCount As Long, _ ByVal nPolyFillMode As Long) As Long Private Declare Function FillRgn _ Lib "gdi32" (ByVal hdc As Long, _ ByVal hRgn As Long, _ ByVal hBrush As Long) As Long Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long' 画一个从(x1, y1)到到(x2, y2)的箭头 Private Sub DrawArrow(ByVal pic As Object, _ ByVal x1 As Single, _ ByVal y1 As Single, _ ByVal x2 As Single, _ ByVal y2 As Single, _ ByVal length As Single) Dim hBrush As Long Dim hRgn As Long Dim lpTPoint(2) As POINTAPIDim vx As Single Dim vy As Single Dim dist As Single Dim i As Integer '画直线 pic.Line (x1, y1)-(x2, y2) '获取直线单位向量 vx = x2 - x1 vy = y2 - y1 dist = Sqr(vx ^ 2 + vy ^ 2) vx = vx / dist vy = vy / dist '顶点 lpTPoint(0).X = x2 lpTPoint(0).Y = y2 ' 右顶点位置 lpTPoint(1).X = x2 + (-vy - vx) * length lpTPoint(1).Y = y2 + (vx - vy) * length '左顶点位置 lpTPoint(2).X = x2 + (vy - vx) * length lpTPoint(2).Y = y2 + (-vx - vy) * length Polygon pic.hdc, lpTPoint(0), 3 ' 获得黑色画刷 hBrush = GetStockObject(BLACK_BRUSH) ' 为了填充颜色创建区域 hRgn = CreatePolygonRgn(lpTPoint(0), 3, ALTERNATE) ' 通过创建成功就使用颜色填充 If hRgn Then FillRgn pic.hdc, hRgn, hBrush
DeleteObject hRgnEnd Sub Private Sub Form_Load() Const BARB_LEN = 10
x = a*cos(n) - b*sin(n)
y = b*cos(n) + a*sin(n)
Form1.Scale (-110, 110)-(110, -110)
Line (-105, 0)-(105, 0)
Line (0, 105)-(0, -105)
CurrentX = 105: CurrentY = 20: Print "x"
CurrentX = 10: CurrentY = 105: Print "y"
For i = -100 To 100 Step 20
CurrentX = i: CurrentY = 7: Line -(i, 0)
CurrentX = i - 5: CurrentY = -5: Print i / 10
Next i
CurrentX = 45: CurrentY = 35: Print "A"
PSet (40, 30), vbRed
Dim xx As Single, yy As Single
For i = 1 To 360 Step 1 xx = 40 * Cos(i) - 30 * Sin(i)
yy = 30 * Cos(i) + 40 * Sin(i)
CurrentX = xx + 5: CurrentY = yy + 5: If i = 90 Then Print "(" & Int(xx) & "," & Int(yy) & ")"
PSet (xx, yy), vbRed
Next
End Sub
Form1.Scale (-110, 110)-(110, -110)
Line (-105, 0)-(105, 0)
Line (0, 105)-(0, -105)
CurrentX = 105: CurrentY = 20: Print "x"
CurrentX = 10: CurrentY = 105: Print "y"
For i = -100 To 100 Step 20
CurrentX = i: CurrentY = 7: Line -(i, 0)
CurrentX = i - 5: CurrentY = -5: Print i / 10
Next i
CurrentX = 45: CurrentY = 35: Print "A"
PSet (40, 30), vbRed
Dim xx As Single, yy As Single
For i = 1 To 360 Step 1 xx = 40 * Cos(i) - 30 * Sin(i)
yy = 30 * Cos(i) + 40 * Sin(i)
CurrentX = xx + 5: CurrentY = yy + 5: If i = 90 Then Print "(" & Int(xx) & "," & Int(yy) & ")"
PSet (xx, yy), vbRed
Next
End Sub
Dim DAngle As Single DAngle = PI / 180 Form1.Scale (-110, 110)-(110, -110)
Line (-105, 0)-(105, 0)
Line (0, 105)-(0, -105)
CurrentX = 105: CurrentY = 20: Print "x"
CurrentX = 10: CurrentY = 105: Print "y"
For i = -100 To 100 Step 20
CurrentX = i: CurrentY = 7: Line -(i, 0)
CurrentX = i - 5: CurrentY = -5: Print i / 10
Next iCurrentX = 45: CurrentY = 35: Print "A"
PSet (40, 30), vbRed
Dim xx As Single, yy As Single
For i = 1 To 360 Step 1 xx = 40 * Cos(i * DAngle) - 30 * Sin(i * DAngle)
yy = 30 * Cos(i * DAngle) + 40 * Sin(i * DAngle)
CurrentX = xx + 5: CurrentY = yy + 5: If i = 90 Then Print "(" & Int(xx) & "," & Int(yy) & ")"
PSet (xx, yy), vbRed
Next
End Sub
y1=(X^2+y^2)^0.5*sin(atn(y/x)+Angle)
同意8楼,实质可由圆的参数方程:
x = r * Cos(n)
y = r * Sin(n)
推得
'
' #define PI 3.14159265
'
' void DrawLineArrow(TCanvas* Canvas, TPoint p0, TPoint p1)
' {
' //对于点(x0,y0)指向(x1,y1)的箭头线,以(x1,y1)为原点,先计算出(x1,y1)
' //指向(x0,y0)的单位向量,箭头线与直线的角度为d,那么就是将这个向量
' //旋转角度d和-d,向量旋转的公式为:
' //(a+b*i)*(cos(d)+i*sin(d)) = a*cos(d)-b*sin(d) + i*(a*sin(d)+b*cos(d))
' //因为上面的向量以(x1,y1)为原点的单位向量,所以还需要乘以一个长度(
' //箭头线的长度),然后加上偏移就可以了。也就是画的箭头线的顶点的坐标为
' //x=x1+L*(a*cos(d)-b*sin(d)), y=y1+L*(a*sin(d)+b*cos(d))。
' //另一个顶点的坐标,将上面的sin(d)换成 -sin(d) 就可以了。
' //上面公式中的a为(x0-x1)/L0, b为(y0-y1)/L0,L0是(x0,y0)与(x1,y1)的长度,
' //L是箭头线的长度(自己设定)。
' float a, b, L0, L, d, x, y;
'
' Canvas->MoveTo(p0.x, p0.y);
' Canvas->LineTo(p1.x, p1.y); //画p0 到 p1 的直线
'
' L0 = sqrt(pow(p0.x-p1.x,2)+pow(p0.y-p1.y,2)); //直线的长度
' a = (p0.x-p1.x)/L0; b = (p0.y-p1.y)/L0; //单位向量的两个分量
' L = 10.0; //箭头线长度,这儿我写成固定的,你可以自己修改或者计算
' d = 30.0/180.0*PI; //箭头线与直线的角度30度,你可以自己调整
' for(int n=0; n<2; n++) {
' x = p1.x+L*(a*cos(d)-b*sin(n==0?d:-d));
' y = p1.y+L*(a*sin(n==0?d:-d)+b*cos(d));
' Canvas->MoveTo(p1.x, p1.y);
' Canvas->LineTo(x, y); //画箭头线
' }
' }Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function MoveTo Lib "gdi32" Alias "MoveToEx" ( _
ByVal hdc As Long, ByVal x As Long, ByVal y As Long, _
Optional lpPoint As Any = 0) As Long
Private Type POINTAPI
x As Long
y As Long
End TypePrivate Const PI = 3.14159265358979Private Sub DrawLineArrow(TCanvas As PictureBox, p0 As POINTAPI, p1 As POINTAPI)Dim a%, b%, L0%, L%, d%, x%, y%
Dim n As Integer MoveTo TCanvas.hdc, p0.x, p0.y
'画p0 到 p1 的直线
LineTo TCanvas.hdc, p1.x, p1.y
'直线的长度
L0 = Sqr((p1.x - p0.x) ^ 2 + (p1.y - p0.y) ^ 2)
'单位向量的两个分量
a = (p0.x - p1.x) / L0
b = (p0.y - p1.y) / L0
'箭头线长度10
L = 10
'箭头线与直线的角度30度
d = 30 / 180 * PI
n = 0
x = p1.x * L * (a * Cos(d) - b * Sin(IIf(n = 0, d, -d)))
y = p1.y * L * (a * Sin(IIf(n = 0, d, -d) + b * Cos(d)))
MoveTo TCanvas.hdc, p1.x, p1.y
'画箭头线
LineTo TCanvas.hdc, x, y
n = 1
x = p1.x * L * (a * Cos(d) - b * Sin(IIf(n = 0, d, -d)))
y = p1.y * L * (a * Sin(IIf(n = 0, d, -d) + b * Cos(d)))
MoveTo TCanvas.hdc, p1.x, p1.y
'画箭头线
LineTo TCanvas.hdc, x, y
n = 2
x = p1.x * L * (a * Cos(d) - b * Sin(IIf(n = 0, d, -d)))
y = p1.y * L * (a * Sin(IIf(n = 0, d, -d) + b * Cos(d)))
MoveTo TCanvas.hdc, p1.x, p1.y
'画箭头线
LineTo TCanvas.hdc, x, y
End Sub
Private Sub Command1_Click() Dim p0 As POINTAPI, p1 As POINTAPI
p0.x = 10: p0.y = 10
p1.x = 120: p1.y = 130
DrawLineArrow Picture1, p0, p1End Sub
Option ExplicitPrivate Type POINTAPI X As Long
Y As LongEnd TypePrivate Const ALTERNATE = 1
Private Const BLACK_BRUSH = 4Private Declare Function Polygon _
Lib "gdi32" (ByVal hdc As Long, _
lpPoint As POINTAPI, _
ByVal nCount As Long) As Long
Private Declare Function GetStockObject Lib "gdi32" (ByVal nIndex As Long) As Long
Private Declare Function CreatePolygonRgn _
Lib "gdi32" (lpPoint As Any, _
ByVal nCount As Long, _
ByVal nPolyFillMode As Long) As Long
Private Declare Function FillRgn _
Lib "gdi32" (ByVal hdc As Long, _
ByVal hRgn As Long, _
ByVal hBrush As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long' 画一个从(x1, y1)到到(x2, y2)的箭头
Private Sub DrawArrow(ByVal pic As Object, _
ByVal x1 As Single, _
ByVal y1 As Single, _
ByVal x2 As Single, _
ByVal y2 As Single, _
ByVal length As Single)
Dim hBrush As Long
Dim hRgn As Long
Dim lpTPoint(2) As POINTAPIDim vx As Single
Dim vy As Single
Dim dist As Single
Dim i As Integer '画直线
pic.Line (x1, y1)-(x2, y2) '获取直线单位向量
vx = x2 - x1
vy = y2 - y1
dist = Sqr(vx ^ 2 + vy ^ 2)
vx = vx / dist
vy = vy / dist '顶点
lpTPoint(0).X = x2
lpTPoint(0).Y = y2 ' 右顶点位置
lpTPoint(1).X = x2 + (-vy - vx) * length
lpTPoint(1).Y = y2 + (vx - vy) * length
'左顶点位置
lpTPoint(2).X = x2 + (vy - vx) * length
lpTPoint(2).Y = y2 + (-vx - vy) * length Polygon pic.hdc, lpTPoint(0), 3
' 获得黑色画刷
hBrush = GetStockObject(BLACK_BRUSH)
' 为了填充颜色创建区域
hRgn = CreatePolygonRgn(lpTPoint(0), 3, ALTERNATE)
' 通过创建成功就使用颜色填充
If hRgn Then FillRgn pic.hdc, hRgn, hBrush
DeleteObject hRgnEnd Sub
Private Sub Form_Load()
Const BARB_LEN = 10
Me.Show
Picture1.AutoRedraw = True
Picture1.ScaleMode = 3 'Twip
'画箭头
DrawArrow Picture1, 20, 40, 100, 50, BARB_LEN
DrawArrow Picture1, 180, 30, 20, 190, BARB_LEN
DrawArrow Picture1, 30, 240, 320, 30, BARB_LEN
DrawArrow Picture1, 100, 240, 270, 240, BARB_LEN
DrawArrow Picture1, 340, 70, 340, 260, BARB_LEN
End Sub
因在本论坛不知怎样上传文件,所以将示例放在下面地址,如合你的要求,我再加以补充完善
请到网页下“旋转示例”试试
http://khjkhj.gbaopan.com/