| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 | <!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; // KGvar EARTH_MASS = 5.97e24; // KGvar 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>
 |