|
本帖最后由 aoe1981 于 2020-2-12 22:50 编辑
这个主题似乎做过了:
玩一玩简单的分形:谢尔宾斯基三角形
http://club.excelhome.net/thread-1517120-1-1.html
(出处: ExcelHome技术论坛)
今天直接说“强大”之处:
(1)正三角形(五心合一):
(2)垂足三角形:
(3)中点三角形:
(4)角分点三角形:
(5)周界中点三角形:
(6)三角形“五心”计算自定义函数:
a.可以返回:三个垂足、三个中点、三个角分点、三个周界中点的坐标;
b.可以返回:垂心、重心、外心、内心、界心的坐标。
工具性自定义函数如下:
一级自定义函数:
- Option Explicit
- Public Function ChuiZu(dd, Optional n% = 0) '1.根据三角形顶点坐标计算垂足坐标(3*2下标相同)或返回垂心坐标(1*2)
- On Error Resume Next
- Dim i&, i1&, i2&, i3&, j1&, j2&, k1#, b1#, k2#, b2#
- If TypeName(dd) = "Range" Then dd = dd.Value
- j1 = UBound(dd, 1) - LBound(dd, 1) + 1
- j2 = UBound(dd, 2) - LBound(dd, 2) + 1
- ReDim cz(1 To 1, 1 To 1)
- If err.Number = 13 Then
- cz(1, 1) = "参数不是数组"
- ChuiZu = cz
- Exit Function
- ElseIf j1 <> 3 Or j2 <> 2 Then
- cz(1, 1) = "参数必须是3行2列的数值数组"
- ChuiZu = cz
- Exit Function
- End If
- j1 = LBound(dd, 1)
- j2 = LBound(dd, 2)
- ReDim cz(j1 To UBound(dd, 1), j2 To UBound(dd, 2))
- For i = 0 To 2
- i1 = j1 + i Mod 3
- i2 = j1 + (i + 1) Mod 3
- i3 = j1 + (i + 2) Mod 3
- If dd(i2, j2) <> dd(i3, j2) And dd(i2, j2 + 1) <> dd(i3, j2 + 1) Then '横坐标、纵坐标均不相同
- k1 = (dd(i2, j2 + 1) - dd(i3, j2 + 1)) / (dd(i2, j2) - dd(i3, j2))
- b1 = (dd(i2, j2) * dd(i3, j2 + 1) - dd(i3, j2) * dd(i2, j2 + 1)) / (dd(i2, j2) - dd(i3, j2))
- k2 = -1 / k1
- b2 = dd(i1, j2 + 1) - k2 * dd(i1, j2)
- cz(i + j1, j2) = (b2 - b1) / (k1 - k2)
- cz(i + j1, j2 + 1) = k1 * cz(i + j1, j2) + b1
- ElseIf dd(i2, j2) = dd(i3, j2) And dd(i2, j2 + 1) <> dd(i3, j2 + 1) Then '横坐标相同、纵坐标不相同
- cz(i + j1, j2) = dd(i2, j2)
- cz(i + j1, j2 + 1) = dd(i1, j2 + 1)
- ElseIf dd(i2, j2) <> dd(i3, j2) And dd(i2, j2 + 1) = dd(i3, j2 + 1) Then '横坐标不相同、纵坐标相同
- cz(i + j1, j2) = dd(i1, j2)
- cz(i + j1, j2 + 1) = dd(i2, j2 + 1)
- Else '横坐标相同、纵坐标相同
- ReDim cz(1 To 1, 1 To 1)
- cz(1, 1) = "数据错误:两点重合"
- ChuiZu = cz
- Exit Function
- End If
- Next i
- If n = 0 Then
- ChuiZu = cz
- Else '垂心
- ChuiZu = ZhiXianJD(dd(j1, j2), dd(j1, j2 + 1), cz(j1, j2), cz(j1, j2 + 1), dd(j1 + 1, j2), dd(j1 + 1, j2 + 1), cz(j1 + 1, j2), cz(j1 + 1, j2 + 1))
- End If
- End Function
- Public Function ZhongDian(dd, Optional n% = 0) '2.根据三角形顶点坐标计算中点坐标(3*2下标相同)或返回重心、外心坐标(1*2)
- On Error Resume Next
- Dim i&, i2&, i3&, j1&, j2&
- If TypeName(dd) = "Range" Then dd = dd.Value
- j1 = UBound(dd, 1) - LBound(dd, 1) + 1
- j2 = UBound(dd, 2) - LBound(dd, 2) + 1
- ReDim zd(1 To 1, 1 To 1)
- If err.Number = 13 Then
- zd(1, 1) = "参数不是数组"
- ZhongDian = zd
- Exit Function
- ElseIf j1 <> 3 Or j2 <> 2 Then
- zd(1, 1) = "参数必须是3行2列的数值数组"
- ZhongDian = zd
- Exit Function
- End If
- j1 = LBound(dd, 1)
- j2 = LBound(dd, 2)
- ReDim zd(j1 To UBound(dd, 1), j2 To UBound(dd, 2))
- For i = 0 To 2
- i2 = j1 + (i + 1) Mod 3
- i3 = j1 + (i + 2) Mod 3
- If dd(i2, j2) = dd(i3, j2) And dd(i2, j2 + 1) = dd(i3, j2 + 1) Then '横坐标相同、纵坐标相同
- ReDim zd(1 To 1, 1 To 1)
- zd(1, 1) = "数据错误:两点重合"
- ZhongDian = zd
- Exit Function
- Else
- zd(i + j1, j2) = (dd(i2, j2) + dd(i3, j2)) / 2
- zd(i + j1, j2 + 1) = (dd(i2, j2 + 1) + dd(i3, j2 + 1)) / 2
- End If
- Next i
- If n = 0 Then
- ZhongDian = zd
- ElseIf n = 1 Then '重心
- ZhongDian = ZhiXianJD(dd(j1, j2), dd(j1, j2 + 1), zd(j1, j2), zd(j1, j2 + 1), dd(j1 + 1, j2), dd(j1 + 1, j2 + 1), zd(j1 + 1, j2), zd(j1 + 1, j2 + 1))
- Else '外心(相当于已知三点求圆心坐标)
- Dim a1#, b1#, c1#, a2#, b2#, c2#, wx(1 To 1, 1 To 2)
- a1 = 2 * (dd(j1, j2) - dd(j1 + 1, j2))
- b1 = 2 * (dd(j1, j2 + 1) - dd(j1 + 1, j2 + 1))
- c1 = dd(j1, j2) ^ 2 + dd(j1, j2 + 1) ^ 2 - dd(j1 + 1, j2) ^ 2 - dd(j1 + 1, j2 + 1) ^ 2
- a2 = 2 * (dd(j1, j2) - dd(j1 + 2, j2))
- b2 = 2 * (dd(j1, j2 + 1) - dd(j1 + 2, j2 + 1))
- c2 = dd(j1, j2) ^ 2 + dd(j1, j2 + 1) ^ 2 - dd(j1 + 2, j2) ^ 2 - dd(j1 + 2, j2 + 1) ^ 2
- wx(1, 1) = (b2 * c1 - b1 * c2) / (a1 * b2 - a2 * b1)
- wx(1, 2) = (a1 * c2 - a2 * c1) / (a1 * b2 - a2 * b1)
- ZhongDian = wx
- End If
- End Function
- Public Function JiaoFenDian(dd, Optional n% = 0) '3.根据三角形顶点坐标计算角分点坐标(3*2下标相同)或返回内心坐标(1*2)
- On Error Resume Next
- Dim i&, i1&, i2&, i3&, j1&, j2&, a#, b#, c#, m#
- If TypeName(dd) = "Range" Then dd = dd.Value
- j1 = UBound(dd, 1) - LBound(dd, 1) + 1
- j2 = UBound(dd, 2) - LBound(dd, 2) + 1
- ReDim jfd(1 To 1, 1 To 1)
- If err.Number = 13 Then
- jfd(1, 1) = "参数不是数组"
- JiaoFenDian = jfd
- Exit Function
- ElseIf j1 <> 3 Or j2 <> 2 Then
- jfd(1, 1) = "参数必须是3行2列的数值数组"
- JiaoFenDian = jfd
- Exit Function
- End If
- j1 = LBound(dd, 1)
- j2 = LBound(dd, 2)
- ReDim jfd(j1 To UBound(dd, 1), j2 To UBound(dd, 2))
- For i = 0 To 2
- i1 = j1 + i Mod 3
- i2 = j1 + (i + 1) Mod 3
- i3 = j1 + (i + 2) Mod 3
- If dd(i2, j2) = dd(i3, j2) And dd(i2, j2 + 1) = dd(i3, j2 + 1) Then '横坐标相同、纵坐标相同
- ReDim jfd(1 To 1, 1 To 1)
- jfd(1, 1) = "数据错误:两点重合"
- JiaoFenDian = jfd
- Exit Function
- Else
- a = ((dd(i2, j2) - dd(i1, j2)) ^ 2 + (dd(i2, j2 + 1) - dd(i1, j2 + 1)) ^ 2) ^ 0.5
- b = ((dd(i3, j2) - dd(i1, j2)) ^ 2 + (dd(i3, j2 + 1) - dd(i1, j2 + 1)) ^ 2) ^ 0.5
- c = ((dd(i3, j2) - dd(i2, j2)) ^ 2 + (dd(i3, j2 + 1) - dd(i2, j2 + 1)) ^ 2) ^ 0.5
- m = a / (a + b)
- jfd(i + j1, j2) = (dd(i3, j2) - dd(i2, j2)) * m + dd(i2, j2)
- jfd(i + j1, j2 + 1) = (dd(i3, j2 + 1) - dd(i2, j2 + 1)) * m + dd(i2, j2 + 1)
- End If
- Next i
- If n = 0 Then
- JiaoFenDian = jfd
- Else '内心
- JiaoFenDian = ZhiXianJD(dd(j1, j2), dd(j1, j2 + 1), jfd(j1, j2), jfd(j1, j2 + 1), dd(j1 + 1, j2), dd(j1 + 1, j2 + 1), jfd(j1 + 1, j2), jfd(j1 + 1, j2 + 1))
- End If
- End Function
- Public Function ZhouJieZhongDian(dd, Optional n% = 0) '4.根据三角形顶点坐标计算周界中点坐标(3*2下标相同)或返回界心坐标(1*2)
- On Error Resume Next
- Dim i&, i1&, i2&, i3&, j1&, j2&, a#, b#, c#, m#
- If TypeName(dd) = "Range" Then dd = dd.Value
- j1 = UBound(dd, 1) - LBound(dd, 1) + 1
- j2 = UBound(dd, 2) - LBound(dd, 2) + 1
- ReDim zjzd(1 To 1, 1 To 1)
- If err.Number = 13 Then
- zjzd(1, 1) = "参数不是数组"
- ZhouJieZhongDian = zjzd
- Exit Function
- ElseIf j1 <> 3 Or j2 <> 2 Then
- zjzd(1, 1) = "参数必须是3行2列的数值数组"
- ZhouJieZhongDian = zjzd
- Exit Function
- End If
- j1 = LBound(dd, 1)
- j2 = LBound(dd, 2)
- ReDim zjzd(j1 To UBound(dd, 1), j2 To UBound(dd, 2))
- For i = 0 To 2
- i1 = j1 + i Mod 3
- i2 = j1 + (i + 1) Mod 3
- i3 = j1 + (i + 2) Mod 3
- If dd(i2, j2) = dd(i3, j2) And dd(i2, j2 + 1) = dd(i3, j2 + 1) Then '横坐标相同、纵坐标相同
- ReDim zjzd(1 To 1, 1 To 1)
- zjzd(1, 1) = "数据错误:两点重合"
- ZhouJieZhongDian = zjzd
- Exit Function
- Else
- a = ((dd(i2, j2) - dd(i1, j2)) ^ 2 + (dd(i2, j2 + 1) - dd(i1, j2 + 1)) ^ 2) ^ 0.5
- b = ((dd(i3, j2) - dd(i1, j2)) ^ 2 + (dd(i3, j2 + 1) - dd(i1, j2 + 1)) ^ 2) ^ 0.5
- c = ((dd(i3, j2) - dd(i2, j2)) ^ 2 + (dd(i3, j2 + 1) - dd(i2, j2 + 1)) ^ 2) ^ 0.5
- m = (a + b + c) / 2 - a
- zjzd(i + j1, j2) = (dd(i3, j2) - dd(i2, j2)) * m / c + dd(i2, j2)
- zjzd(i + j1, j2 + 1) = (dd(i3, j2 + 1) - dd(i2, j2 + 1)) * m / c + dd(i2, j2 + 1)
- End If
- Next i
- If n = 0 Then
- ZhouJieZhongDian = zjzd
- Else '界心
- ZhouJieZhongDian = ZhiXianJD(dd(j1, j2), dd(j1, j2 + 1), zjzd(j1, j2), zjzd(j1, j2 + 1), dd(j1 + 1, j2), dd(j1 + 1, j2 + 1), zjzd(j1 + 1, j2), zjzd(j1 + 1, j2 + 1))
- End If
- End Function
复制代码
其实:三角形还有“一心”,叫做“旁心”,这个旁心有三个,与本帖做的迭代“谢尔宾斯基三角形”主程序代码在思路上不一致,故而没做,以后有闲心的再补吧……
附件如下:
谢尔宾斯基三角形1.zip
(218.96 KB, 下载次数: 13)
(附件更新至3楼说明,主要内容是:补充完整了三角形“六心”)
(这个附件耗时多日啊,是我的原创,不似前一个,只是为了验证一组“仿射变换”,本附件完全是从“迭代三角形”出发考虑的,关于迭代三角形还有很多有趣的问题,非发疯不足完成啊……)
|
评分
-
1
查看全部评分
-
|