如何在曲面上布置各種體塊?建築師編程指南之SketchUp插件開發 3

  • 2019 年 11 月 12 日
  • 筆記

今天整理文章,發現《建築師編程指南》這個系列,還沒更完,有好幾篇都躺在草稿箱里沒發,發現網上關於sketchup的編程資料太少,不繼續更好像不太好?

關於這個系列,不熟悉的可以翻閱前2期。

01期 建築師編程指南之SketchUp插件開發

02期 ruby 語言的特點,以及閱讀 SketchUp API 文檔的技巧

第三篇,來點複雜,用代碼實現一個案例:

猶太人大屠殺紀念碑群

第二次世界大戰中,600萬猶太人在種族清洗中被屠殺。

這個作品我非常喜歡,今天我們用代碼來實現此類雕塑群的生成設計,首先我們需要提煉影響設計的變量有哪些,假設 M 為設計結果,

M = ( Grid , Heights )

Grid 為每一個紀念碑的截面,假設每個截面都是相等的大小,間距也相等, Heights 為高度數據集。

實現邏輯

01

根據區域範圍,及方塊大小,生成網格

在這裡區域範圍,我們粗暴點認為是矩形區域,通過 _size 來設置, _grid 則上文的 Grid ,_originPoint 為原點。

只要把上圖中的黑點坐標計算出來,就可以完成我們這一步的任務。

這裡我們需要考慮下,希望通過 createGrid 函數獲得怎麼樣的輸出結果?

寫成代碼:

_originPoint=[0,0,0]    _size={    "width"=>36000,    "height"=>36000    }    _grid={    "width"=>300,    "height"=>800    }    pointsResult=createGrid(_originPoint,_size,_grid)

createGrid 函數的編寫:

def createGrid(_originPoint,_size,_grid)        #間距固定,設定為常量。      _px=600      _py=500        _w=_size["width"]      _h=_size["height"]      _z=_originPoint[2]        _x=_originPoint[0]      _y=_originPoint[1]        _gw=_grid["width"]      _gh=_grid["height"]        _xNum=(_w/(_gw+_px)).floor.to_f      _yNum=(_h/(_gh+_py)).floor.to_f        _points={         "row"=> 0       }        for i in 1..(_xNum-1)           _pointX1=_x+(_gw+_px)*(i-1)         _pointX2=_x+(_gw+_px)*i-_px           #p [_pointX1,_pointX2]         _gpoints=[]           for j in 1..(_yNum-1)           _pointY1=_y+(_gh+_py)*(j-1)           _pointY2=_y+(_gh+_py)*j-_py             _point1=[_pointX1,_pointY1,_z]           _point2=[_pointX1,_pointY2,_z]           _point3=[_pointX2,_pointY2,_z]           _point4=[_pointX2,_pointY1,_z]             _gpoints.push([_point1,_point2,_point3,_point4])             if j==1 && i==1              #調試用的              #p [_point1,_point2,_point3,_point4]           end           end           _points[_points["row"]]=_gpoints         _points["row"]=_points["row"]+1          end        return _points    end

02

計算高度

高度我們先選 sin 函數來生成,通過峰值數量 _peakValue ,及生成數值的間距 _parts 來控制。

createHeights 方法如下:

def createHeights(_peakValue,_parts)      _res=[]    _np=(_peakValue+2)*Math::PI/_parts      for x in 1.._parts        y=Math.sin(x*_np)      _res.push(y)      end      #p _res      return _res    end

通過以下代碼調用:

_peakValue=3  _parts=pointsResult["row"]  _zsOfRow=createHeights(_peakValue,_parts)

這部分光 p 出來看數據可能比較抽象,我們加一段在 SketchUp 里繪製點的命令,把數據畫出來。

model = Sketchup.active_model  entities = model.active_entities    for x in 0..(_zsbyRow.length-1)     entities.add_cpoint [x,_zsOfRow[x],0]  end

是不是調試起來方便多了?也可以把段封裝成方法,專用來調試使用。

上面只計算了一個方向的,另一個方向我們也計算下:

_peakValueOfColumn=1  _partsOfColumn=pointsResult[0].length    _zsOfColumn=createHeights(_peakValueOfColumn,_partsOfColumn)

這個時候,我們調試的代碼可以把 x , y 坐標對調下:

 for x in 0..(_zsOfColumn.length-1)       entities.add_cpoint [_zsOfColumn[x],x,0]   end

這樣的話,調試起來更方便了,可以快速的把 x , y 兩個軸的高度變化顯示出來。

接下來,根據高度拉伸網格中的方塊,此部分交給大家自行實現啦~

以上是去年的思考,實現之後會發現,Heights很難做到絲滑過度、連續變化的感覺。Heights的獲取,有沒有一種更好、更為優雅,簡潔的實現方式呢?

回到開頭所提到的公式:

M = ( Grid , Heights )

Heights究竟如何生成比較好呢?今天我們引入 曲面 來生成Heights。通過su,我們可以快速地通過手繪曲線,然後使用sandbox工具快速生成地形,如下圖:

通過在地形表面上捕獲若干的網格點,我們就可以獲得高低起伏的Heights數據啦~

03

試驗下效果

利用地形生成連續變化的Heights,更容易控制,也更容易實現。

實現的主要代碼及涉及到的知識點,會在後面的更新中發佈出來,有興趣也可以加入mixlab無界社區的社群,一起探討,研究,學習~~

本期的技巧:

通過地形來產生連續變化的Heights

你get到了嗎?