{"id":3833,"date":"2016-03-08T16:37:17","date_gmt":"2016-03-08T14:37:17","guid":{"rendered":"https:\/\/yehar.com\/blog\/?p=3833"},"modified":"2023-12-25T20:41:57","modified_gmt":"2023-12-25T18:41:57","slug":"3833","status":"publish","type":"post","link":"https:\/\/yehar.com\/blog\/?p=3833","title":{"rendered":"Teardrop simulation"},"content":{"rendered":"For more info see this <a href=\"http:\/\/math.stackexchange.com\/questions\/1447021\/function-to-describe-teardrop-shape\/1678533\">Mathematics StackExchange post<\/a> with my reply.\r\n<div id='simulationBox1'><\/div>\r\n<div id='simulationInfo1'><\/div>\r\n<div id='simulationInfo2'><\/div>\r\n<script src=\"\/matter.min.js\" type=\"text\/javascript\"><\/script>\r\n<script type=\"text\/javascript\">\r\nvar particleEngine = Matter.Engine.create({constraintIterations:300, positionIterations:20, timing:{timeScale: 0.1}});\r\n\/\/ create a renderer\r\nvar render = Matter.Render.create({\r\n    element: document.getElementById(\"simulationBox1\"),\r\n    engine: particleEngine,\r\n    wireframes: true,\r\n    showAngleIndicator: false\r\n});\r\nvar N = 100; \/\/ Number of pearls\r\nvar S = 5; \/\/ Pearl radius\r\nvar L = 10; \/\/ Link length\r\nvar M = 700; \/\/ Number of filling particles (try 730)\r\ndocument.getElementById('simulationInfo1').innerHTML='<b>Simulation 1<\/b><br \/>Number of pearls: N = '+N+'<br \/>Pearl radius: S = '+S+'<br \/> Link length: L = '+L+'<br \/> Filling particle count: M = '+ M;\r\nparticleEngine.world.gravity.y = 0.04; \/\/ try 0.04\r\nvar stack = Matter.Composite.create();\r\nfor (var i = 0; i < M; i++) {\r\n  Matter.Composite.add(stack, Matter.Bodies.circle(400+Matter.Common.random(-N*L\/Math.PI\/3, N*L\/Math.PI\/3), 15+N*L\/Math.PI\/2+Matter.Common.random(-N*L\/Math.PI\/3, N*L\/Math.PI\/3), Matter.Common.random(2, 8), { friction: 0, restitution: 0, density: 1, collisionFilter: {category: 1}}));\r\n};\r\nvar bridge = Matter.Composite.create();\r\nfor (var i = 0; i < N; i++) {\r\n  Matter.Composite.add(bridge, Matter.Bodies.circle(400 + N*L\/(Math.PI*2)*Math.sin(2*Math.PI*i\/N), 15+N*L\/(Math.PI*2) - N*L\/(Math.PI*2)*Math.cos(2*Math.PI*i\/N), S, {friction: 0, restitution: 0, density:0.5, collisionFilter: {category: 2, mask: 1}, isStatic: i == 0}));\r\n}\r\nfor (var i = 0; i < N; i++) {\r\n  Matter.Composite.add(particleEngine.world, Matter.Constraint.create({bodyA: bridge.bodies[i], pointA: { x: 0, y: 0 }, bodyB: bridge.bodies[(i+1)%N], pointB: { x: 0, y: 0 }, stiffness:7, length:L,render:{strokeStyle:'#00ffff'}}));\r\n}\r\nMatter.Composite.add(particleEngine.world, [\r\n  stack,\r\n  bridge,\r\n  Matter.Bodies.rectangle(400, -40, 800, 10, { isStatic: true })\r\n]);\r\nMatter.Events.on(render, \"afterRender\", function(a){\r\n  var str = 'Circumference:';\r\n  var checksum = 0;\r\n  var len = 0;\r\n  for (var i = 0; i < N; i++) { \r\n    len += Math.sqrt(Math.pow(bridge.bodies[i].position.x-bridge.bodies[(i+1)%N].position.x, 2) + Math.pow(bridge.bodies[i].position.y-bridge.bodies[(i+1)%N].position.y, 2));\r\n  }\r\n  var x0 = bridge.bodies[0].position.x-bridge.bodies[1].position.x;\r\n  var y0 = bridge.bodies[0].position.y-bridge.bodies[1].position.y;\r\n  var x1 = bridge.bodies[0].position.x-bridge.bodies[N-1].position.x;\r\n  var y1 = bridge.bodies[0].position.y-bridge.bodies[N-1].position.y;\r\n  str += ' '+len.toString()+'<br \/> Tail tip angle (degrees): '+(((Math.atan2(y1, x1) - Math.atan2(y0, x0))*180\/Math.PI + 360)%360).toString()+'<p \/>';\r\n  document.getElementById('simulationInfo2').innerHTML=str;\r\n});\r\nvar lemniscate = Matter.Composite.create()\r\nvar trix = Matter.Composite.create()\r\nfor (var i = 0; i < N; i++) {\r\n  var s = 1.9150080481545374814*(2.0*i\/(N)-1);\r\n  Matter.Composite.add(trix, Matter.Bodies.circle(400 + L*N*(s - 2*Math.tanh(s))\/3.8295479369488985, 15 + L*N*(2\/Math.cosh(s) - 0.57683981788998291629)\/3.8295479369488985, 1, {isStatic: true}));\r\n}\r\nfor (var i = 0; i < N; i++) {\r\n  Matter.Composite.add(particleEngine.world, Matter.Constraint.create({bodyA: trix.bodies[i], bodyB: trix.bodies[(i+1)%N],render:{strokeStyle:'#ff0000'}}));\r\n}\r\nMatter.Render.run(render)\r\nMatter.Runner.run(particleEngine);\r\n<\/script>","protected":false},"excerpt":{"rendered":"For more info see this Mathematics StackExchange post with my reply.","protected":false},"author":1,"featured_media":3865,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,10],"tags":[],"_links":{"self":[{"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3833"}],"collection":[{"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3833"}],"version-history":[{"count":54,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3833\/revisions"}],"predecessor-version":[{"id":4582,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3833\/revisions\/4582"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=\/wp\/v2\/media\/3865"}],"wp:attachment":[{"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yehar.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}