{"id":19876699,"url":"https://github.com/dirktoewe/strandbeest_sim","last_synced_at":"2026-07-06T07:30:58.057Z","repository":{"id":176082594,"uuid":"63314883","full_name":"DirkToewe/strandbeest_sim","owner":"DirkToewe","description":"A rudimentary 2D Kinematics simulation using Strandbeest legs as example.","archived":false,"fork":false,"pushed_at":"2016-07-14T17:52:01.000Z","size":3710,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-24T05:35:08.533Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DirkToewe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-14T07:54:47.000Z","updated_at":"2024-12-15T16:22:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"b7721133-c920-46d2-acd8-f8658ef76020","html_url":"https://github.com/DirkToewe/strandbeest_sim","commit_stats":null,"previous_names":["dirktoewe/strandbeest_sim"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DirkToewe%2Fstrandbeest_sim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DirkToewe%2Fstrandbeest_sim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DirkToewe%2Fstrandbeest_sim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DirkToewe%2Fstrandbeest_sim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DirkToewe","download_url":"https://codeload.github.com/DirkToewe/strandbeest_sim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241304294,"owners_count":19941101,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T16:33:58.020Z","updated_at":"2025-11-03T15:02:58.175Z","avatar_url":"https://github.com/DirkToewe.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Python Strandbeest Simulation\n=============================\nMy second Python Project is an application that allows the 2D Kinematics simulation of simple rod and ball\njoint frameworks. As an example the movement of a [Strandbeest](https://en.wikipedia.org/wiki/Strandbeest)\nleg is simulated. The app is an ideal introduction to Python in mechanical engineering as it covers two key\naspects: Visualization and Numerics.\n\n\u003cimg src=\"https://github.com/DirkToewe/strandbeest_sim/blob/master/strandbeest_sim.gif\" width=\"60%\"\u003e\n\nModel\n=====\nA ```Model``` consists of:\n  * a set of nodes. Each node has a unique name and a current position (x,y)\n  * a set edges (or rods), specified by the name of the two edges it connects\n  * a set of boundary constraints that constrain the movement of the nodes\n\nEach node introduces two degrees of freedom to the model (x and y). A rod enforces a constant distance\nbetween two edges. Each rod constrains one degree of freedom. The boundary constraints constrain the\nmovement of a node. The NodeMoveBC constrains the speed of a node alongside a direction vector. The\nvelocity orthogonal to the direction is not constrained. Each NodeMoveBC there constrains one degree\nof freedom. The RotationBC constrains a node to move in a circular motion around a pivot point.\nIt constraings two degrees of freedom. If there is as many (rendundancy free) constraints as\nthere are degrees of freedom, the system is terminate and can be simulated.\n\nNodes are added via the ```addNode()``` method, edges via ```addEdge()```. Boundary constraints\nare added directly to the ```bcs``` list.\n\n```python\nimport Strandbeest\n\nleg = Strandbeest.Model()\nleg.addNode('p0',   0.,             0.)\nleg.addNode('p1', -35.0353991829,  19.5071987762)\nleg.addNode('p2',  17.7855809088,  37.4956412365)\nleg.addNode('p3',  50.7538954493,  -0.0954512769988)\nleg.addNode('p4',  2.77183874468, -39.2021288959)\nleg.addNode('p5', -17.0054756067, -84.0335669394)\nleg.addNode('p6', -28.0419102143, -19.2671627536)\nleg.addEdge('p0','p1')\nleg.addEdge('p0','p2')\nleg.addEdge('p0','p4')\nleg.addEdge('p1','p2')\nleg.addEdge('p1','p6')\nleg.addEdge('p2','p3')\nleg.addEdge('p3','p4')\nleg.addEdge('p4','p5')\nleg.addEdge('p4','p6')\nleg.addEdge('p5','p6')\nleg.bcs += [\n  Strandbeest.NodeMoveBC(leg,'p0',(1,0),0),\n  Strandbeest.NodeMoveBC(leg,'p0',(0,1),0),\n  Strandbeest.RotationBC(leg,'p3',(38,7.8),-1)\n]\n```\n\nThe ```Model::increment()``` method advances the simulation by the specified time step ```dt```. The node\npositions change accordingly. The [Runge Kutta Method (RK4)](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods)\nis used to numerically integrate the node movements. Generally speaking, the simulation precision increases\nwith smaller time steps.\n\nWidget\n======\nThe ```Strandbeest.Widget``` allows the visualization and inspection of the ```Model```'s simulation results.\nOnce a ```Model``` submitted to the ```Widget``` it must not be modified. The ```Widget``` is handled like\na regular [PyQt4](https://wiki.python.org/moin/PyQt) [QWidget](http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html),\nwith the difference of taking a ```Model``` as constructor argument:\n\n```python\nfrom PyQt4.QtGui import QApplication\nimport sys\nimport Strandbeest\n\napp = QApplication(sys.argv)\nwdgt = Strandbeest.Widget(model)\nwdgt.setGeometry(200,200,800,600)\nwdgt.show()\nsys.exit( app.exec_() )\n```\n\nThe Start/Stop button on the upper left hand of the window allows to start and stop the animation. The slider\nchanges the animation speed. Moving the mouse over the nodes displays the name of the nodes. A secondary mouse\nbutton click on a node opens a context menu that allows to display a movement curve for the node and allows\nto display the nodes values in a separate diagram.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirktoewe%2Fstrandbeest_sim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdirktoewe%2Fstrandbeest_sim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirktoewe%2Fstrandbeest_sim/lists"}