UNPKG

kity

Version:
205 lines (169 loc) 5.7 kB
<!DOCTYPE html> <html> <head> <!-- 必须强制指定页面编码为 UTF-8 --> <meta charset="utf-8"> <!-- Demo 的简要说明,必须要填写 --> <meta name="description" content="使用 Kity 模拟三体运动"> <!-- Demo 的作者,建议填写 --> <meta name="author" content="techird@qq.com"> <!-- Demo 的标题,必须填写 --> <title>三体运动</title> <!-- Demo 开发过程中使用 CMD 引入 Kity 源码,方便调试 --> <!-- dev start --> <!-- 目录型的 Demo 注意修正源码引用路径 --> <script src="../dev-lib/sea.js"></script> <script> // 设置好 kity 源代码目录 seajs.config( { base: '../src'} ); // 定义 Demo 模块 define('demo', function(require) { var kity = require('kity'); var Draggable = require('../demo/public/draggable'); kity.extendClass( kity.Paper, Draggable ); }); </script> <script> // 启动 Demo 模块 seajs.use('demo'); </script> <!-- dev end --> <!-- 生产使用中可以直接引用发布压缩的版本 --> <!-- production start --> <!-- 目录型的 Demo 注意修正源码引用路径 --> <!-- <script src="../dist/kity.min.js"></script> --> <!-- production end --> <style> body, div, html { margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> <div id="clock" style="width: 100%; height: 100%; position: absolute;"></div> </body> <script> var G = 6.67e-11; var SUN_MASS = 1.99e30; // KG var EARTH_MASS = 5.97e24; // KG var R_SUN_EARTH = 1.52e11; // meter // 绘图画布 var paper = new kity.Paper('clock').pipe(function() { this.setWidth('100%').setHeight('100%'); this.setViewBox(-500, -500, 1000, 1000); this.setStyle('background', 'black'); }).drag(); var Body = kity.createClass('Body', { base: kity.Group, constructor: function() { this.callBase(); this.shift = new kity.Vector(); this.velocity = new kity.Vector(); this.force = new kity.Vector(); this.mass = 1; this.size = 5; this.draw(); }, draw: function() { return this.addShape(new kity.Circle(this.size).fill('white')); } }); var ZERO = 1e-3; var bodies; function randomVector(min, max) { return new kity.Vector(min + Math.random() * (max - min), min + Math.random() * (max - min)); } function randomize() { bodies.forEach(function(body) { body.shift = randomVector(-300, 300); body.velocity = randomVector(-100, 100); body.mass = 10 * Math.random(); body.size = 2 + body.mass; }); } function collision(a, b) { if (a.velocity.length() <= ZERO && b.velocity.length() <= ZERO) return false; // a connect from a to b var connect = kity.Vector.fromPoints(a.shift, b.shift); // v projection on the connect var avc = a.velocity.project(connect), bvc = b.velocity.project(connect); // v delta on the connect var dvc = avc.minus(bvc); // should check the dcv same direction with the connect // and the two ball is close enougth if (dvc.dot(connect) > 0 && connect.length() - a.size - b.size <= ZERO) { var normal = connect.vertical(); var avn = a.velocity.project(normal), bvn = b.velocity.project(normal); // 连线方向速度交换,垂直方向速度不变 var factor = 1; a.velocity = avn.add(bvc).multipy(factor); b.velocity = bvn.add(avc).multipy(factor); return true; } return false; } G = 30000; function simulate(frame) { var tick = 100; while (tick--) { bodies.forEach(function(body) { body.force = new kity.Vector(); bodies.forEach(function(body2) { if (body2 != body) { collision(body, body2); var r = kity.Vector.fromPoints(body.shift, body2.shift); var f = G * body.mass * body2.mass / (r.square()); body.force = body.force.add(r.normalize(f)); } }); body.acceleration = body.force.multipy(1 / body.mass); body.velocity = body.velocity.add(body.acceleration.multipy(0.0005)); body.shift = body.shift.add(body.velocity.multipy(0.0005)); }); } bodies.forEach(function(body) { body.setTranslate(body.shift); body.getShape(0).setRadius(body.size); }); frame.next(); } function init() { bodies = [new Body(), new Body(), new Body(), new Body(), new Body(), new Body(), new Body()]; paper.addShapes(bodies); paper.on('dblclick', randomize); randomize(); kity.requestFrame(simulate); } function triple() { var a = bodies[0], b = bodies[1], c = bodies[2]; a.mass = b.mass = 500; a.size = b.size = 5; a.shift = new kity.Vector(0, 200); b.shift = new kity.Vector(0, -200); a.velocity = new kity.Vector(100, 0); b.velocity = new kity.Vector(-100, 0); c.mass = 0; c.shift = new kity.Vector(10000, 100000); } function triangle() { var a = bodies[0], b = bodies[1], c = bodies[2]; a.mass = b.mass = c.mass = 1050; a.size = b.size = c.size = 5; a.shift = kity.Vector.fromPolar(200, 0); b.shift = kity.Vector.fromPolar(200, 120); c.shift = kity.Vector.fromPolar(200, 240); a.velocity = kity.Vector.fromPolar(300, 60); b.velocity = kity.Vector.fromPolar(300, 180); c.velocity = kity.Vector.fromPolar(300, 300); } init(); </script> </html>