请教一个打印图形的算法,这个算法怎么写
vb吧
全部回复
仅看楼主
level 8
tbzp666 楼主
2023年02月10日 01点02分 1
level 8
tbzp666 楼主
完全看不懂题意,n=3和n=5是什么意思,肯定不是n等分点,第一个图是三等分点,第二个图不是五等分点
2023年02月10日 01点02分 2
level 1
第一次是画一个三角形
后续每次在三个角落的三角形中画倒三角
2023年02月10日 03点02分 3
只要别真去求中点,用三角函数求坐标点还是挺简单的
2023年02月10日 03点02分
level 1
有一些变量可以直接算在公式里,以达成最简。我为了方便理解没简化。用到的一些矢量长度和方向属于数学知识,不作过多注释。没有写触发过程,如有需要自己加入按钮自己写。ClearLine过程也没用到,用于清除当前已经生成的所有线条用的。
'请于窗口中创建一根Line控件,控件名Line1,Index属性改为0,Visible改为False
'注:由于Form窗口中坐标系为从上至下,所以正三角形和反三角形互换
Dim LineNum As Integer '记录线段生成数量
Dim Pi As Double '派,3.14159.....,在Form_Load中赋值
'开始递归,因为第一次生成的三角形是正三角,所以第一次单独写
'N:=递归次数;Pt:=表述三角形中心点;SideLength:=边长
Sub StartRecursion(N As Byte, PtX As Double, PtY As Double, SideLength As Double)
CreateTriangle PtX, PtY, SideLength, False '生成正三角形
RecursionTriangle N - 1, PtX, PtY, SideLength / 2 '开始递归
End Sub
'递归生成三角形
'N:=递归次数;Pt:=表述三角形中心点;SideLength:=边长
Sub RecursionTriangle(N As Byte, PtX As Double, PtY As Double, SideLength As Double)
If N = 0 Then Exit Sub '递归结束
CreateTriangle PtX, PtY, SideLength, True '生成反三角形
'以中心点加上一个矢量,下一个递归的中心点,易证得矢量长度为六分之根号三边长(初中几何)
'易证得递归后,三角形边长减半(初中几何)
Dim Tadian As Double '暂存矢量的弧度
For i = 0 To 2 '递归计算
Tadian = (i * 120 + IIf(IsPositiveTriangle, 90, 30)) * Pi / 180
RecursionTriangle N - 1, Cos(Tadian) * Sqr(3) / 3 * SideLength + PtX, Sin(Tadian) * Sqr(3) / 3 * SideLength + PtY, SideLength / 2
Next
End Sub
'创建三角形
'Pt:=表述三角形中心点;SideLength:=边长;IsPositiveTriangle:=是不是正三角形(由于Top属性方向,实际效果相反)
Sub CreateTriangle(PtX As Double, PtY As Double, SideLength As Double, IsPositiveTriangle As Boolean)
'以中心点加上一个矢量,得到三个角点,易证得矢量长度为三分之根号三边长(初中几何)
Dim Tadian As Double '暂存矢量的弧度
Dim nPtX(2) As Double, nPtY(2) As Double '三个角点坐标
For i = 0 To 2
Tadian = (i * 120 + IIf(IsPositiveTriangle, 90, 30)) * Pi / 180
nPtX(i) = Cos(Tadian) * Sqr(3) / 3 * SideLength + PtX
nPtY(i) = Sin(Tadian) * Sqr(3) / 3 * SideLength + PtY
Next
For i = 0 To 2
CreateLine nPtX(i), nPtY(i), nPtX((i + 1) Mod 3), nPtY((i + 1) Mod 3)
Next
End Sub
'创建边线
Sub CreateLine(Pt1X As Double, Pt1Y As Double, Pt2X As Double, Pt2Y As Double)
LineNum = LineNum + 1
Load Line1(LineNum)
Line1(LineNum).X1 = Pt1X: Line1(LineNum).Y1 = Pt1Y
Line1(LineNum).X2 = Pt2X: Line1(LineNum).Y2 = Pt2Y
Line1(LineNum).Visible = True
End Sub
'角度转弧度
Function AngleToTadian(Angle As Double) As Double
AngleToTadian = Angle * Pi / 180
End Function
'清除所有线条
Sub ClearLine()
For i = 1 To LineNum
unloud Line1(i)
Next
LineNum = 0
End Sub
Private Sub Form_Load()
Pi = Atn(1) * 4
Dim N As Byte '递归数量
Dim X As Double, Y As Double '初始三角形中心点
Dim L As Double '初始三角形边长
N = 10
X = 10000
Y = 10000
L = 16000
StartRecursion N, X, Y, L
End Sub
2023年02月10日 05点02分 4
本代码为抛砖引玉,如有更精简的方法,勿喷
2023年02月10日 05点02分
level 1
2023年02月10日 06点02分 5
level 1
求中点做法,23行,不使用“:”,我的极限精简[呵呵]
Sub RecursionTriangle(ByVal N As Byte, ParamArray Pt() As Variant)
For i = 0 To 5 Step 2
CreateLine (Pt(i Mod 6) + Pt((i + 2) Mod 6)) / 2, (Pt((i + 1) Mod 6) + Pt((i + 3) Mod 6)) / 2, (Pt((i + 4) Mod 6) + Pt((i + 2) Mod 6)) / 2, (Pt((i + 5) Mod 6) + Pt((i + 3) Mod 6)) / 2
If N > 0 Then RecursionTriangle N - 1, Pt((i + 2) Mod 6), Pt((i + 3) Mod 6), Line1(Line1.Count - 1).X1, Line1(Line1.Count - 1).Y1, Line1(Line1.Count - 1).X2, Line1(Line1.Count - 1).Y2
Next
End Sub
Private Sub StartRecursion(N As Byte, Pt As Variant)
For i = 0 To 5 Step 2
CreateLine Pt(i Mod 6), Pt((i + 1) Mod 6), Pt((i + 2) Mod 6), Pt((i + 3) Mod 6)
Next
RecursionTriangle N - 2, Pt(0), Pt(1), Pt(2), Pt(3), Pt(4), Pt(5)
End Sub
Sub CreateLine(ParamArray Pt() As Variant)
Load Line1(Line1.Count)
Line1(Line1.Count - 1).X1 = Pt(0)
Line1(Line1.Count - 1).Y1 = Pt(1)
Line1(Line1.Count - 1).X2 = Pt(2)
Line1(Line1.Count - 1).Y2 = Pt(3)
Line1(Line1.Count - 1).Visible = True
End Sub
Private Sub Form_Load()
StartRecursion 3, Array(1000
#, 8000#
, 7000
#, 8000#
, 4000#, 8000 - 3000 * Sqr(3))
End Sub
2023年02月10日 09点02分 9
StartRecursion 3, Array(1000
#, 8000#
, 7000
#, 8000#
, 4000#, 8000 - 3000 * Sqr(3))中,3是N,Array()的六个数字是三角形三个点坐标
2023年02月10日 09点02分
level 15
这题目我6年前做过[滑稽]
当时就考虑了两种算法,一种是在三角形中画倒三角形,另一种是把整个图形以最小的三角形为单位进行拆分然后分别画出每个三角形
两种算法复杂度相差不大,但是第二种画出来的图形明显不如第一种好看,最外圈的大三角形的边明显都不是直的[滑稽]
代码及运行截图如下:(界面中有两个图片框,分别用的是两种算法,对应两个递归过程Draw1和Draw2)
2023年02月10日 12点02分 10
原来是用picture.line画的吗,我以为是直接用line控件[小乖]。题目我也看岔劈了,采用递归子过程程序最简洁,被我读成了用递归子过程写出最简洁的代码[黑线]
2023年02月10日 14点02分
等我简化成23行才发现题目读错了[喷]
2023年02月10日 14点02分
1