Moin,
da ich in letzter Zeit ein bisschen was mit Subdivisionsoberflächen (eigentlich in 3D) zu tun hatte dachte ich es wäre lustig ein Schema für 2D zu basteln. Vorab. Ich habe dazu nichts gelesen (zumindest für 2D), kann also gut sein, dass es gar nichts neues ist. Falls es doch neu ist, bitte als "Superduper Mars Subdivision" zitieren um alle zu verärgern
Sollte mit Polygonen >= 3 Punkten funktionieren.
Code
Local $aPoints = [[0, 0, 0], [1, 0, 0.5], [1, 1, 1], [0, 1, 0.01]]
Local $aNew = _SubD_GenerateFrom($aPoints, 7)
For $i = 0 To UBound($aNew) - 1 Step 1
ConsoleWrite($aNew[$i][0] & ' ' & $aNew[$i][1] & @CRLF)
Next
; $aPoints[i][3]
; [i][0] = x
; [i][1] = y
; [i][2] = crease: 0.0: sharp, 0.5: balanced, >0.5: pushed
Func _SubD_GenerateFrom($aPoints, $iLevel = 1)
If $iLevel = 0 Then Return $aPoints
Local $n = UBound($aPoints)
If UBound($aPoints, 2) <> 3 Then Return SetError(1, 0, ConsoleWrite('! _SubD_GenerateFrom($aPoints[' & $n & '][' & UBound($aPoints, 2) & '], ' & $iLevel & '): Points needs [i][3] with [x, y, crease].' & @CRLF))
If $n < 3 Then Return SetError(2, 0, ConsoleWrite('! _SubD_GenerateFrom($aPoints[' & $n & '][3], ' & $iLevel & '): Requires >= 3 points.' & @CRLF))
Local $aNew[$n * 2][3], $iP, $iC, $iN
For $i = 0 To $n - 1 Step 1
$iC = 2 * $i
$aNew[$iC][0] = $aPoints[$i][0]
$aNew[$iC][1] = $aPoints[$i][1]
$aNew[$iC][2] = $aPoints[$i][2]
$aNew[$iC + 1][0] = ($aPoints[$i][0] + $aPoints[Mod($i + 1, $n)][0]) / 2
$aNew[$iC + 1][1] = ($aPoints[$i][1] + $aPoints[Mod($i + 1, $n)][1]) / 2
$aNew[$iC + 1][2] = ($aPoints[$i][2] + $aPoints[Mod($i + 1, $n)][2]) / 2
Next
For $i = 0 To $n - 1 Step 1
$iC = 2 * $i
$iP = Mod($iC + 2 * $n - 1, $n * 2)
$iN = Mod($iC + 1, $n * 2)
$aNew[$iC][0] = $aNew[$iC][2] * ($aNew[$iP][0] + $aNew[$iN][0]) / 2 + (1 - $aNew[$iC][2]) * $aNew[$iC][0]
$aNew[$iC][1] = $aNew[$iC][2] * ($aNew[$iP][1] + $aNew[$iN][1]) / 2 + (1 - $aNew[$iC][2]) * $aNew[$iC][1]
$aNew[$iC][2] = $aNew[$iC][2] * ($aNew[$iP][2] + $aNew[$iN][2]) / 2 + (1 - $aNew[$iC][2]) * $aNew[$iC][2]
$aNew[$iC][2] = Sqrt($aNew[$iC][2] / 2); -> moves closer to 0.5 each iteration
Next
If $iLevel > 1 Then Return _SubD_GenerateFrom($aNew, $iLevel - 1)
Return $aNew
EndFunc
Alles anzeigen
Viel Spaß damit. Auf dass die 2D Polygone ein bisschen "runder" werden ![]()
lg
M