雙擺運(yùn)動(dòng)仿真背后的原理

背景

傳統(tǒng)的雙擺系統(tǒng)通常由兩個(gè)長(zhǎng)度分別為l1 ,l2 的細(xì)桿和兩個(gè)固定在細(xì)桿末端怀跛,質(zhì)量為m1 拣宰,m2 的小球組成轩端。內(nèi)擺和垂直線之間的夾角為θ1 放典。外擺與垂直線之間的夾角為θ2 。細(xì)桿的質(zhì)量和球的形狀對(duì)于不同的研究人員有所不同基茵。本文研究理想狀態(tài)奋构,即系桿的質(zhì)量、系統(tǒng)阻尼和阻力忽略不計(jì)拱层,小球看做質(zhì)點(diǎn)弥臼。雙擺系統(tǒng)簡(jiǎn)圖如圖1所示。


圖1 雙擺結(jié)構(gòu)簡(jiǎn)圖

模型建立

此處模型建立利用拉格朗日力學(xué)原理根灯,拉格朗日力學(xué)(Lagrangian mechanics)是分析力學(xué)中的一種径缅,于1788年由約瑟夫·拉格朗日所創(chuàng)立。拉格朗日力學(xué)是對(duì)經(jīng)典力學(xué)的一種的新的理論表述烙肺,著重于數(shù)學(xué)解析的方法纳猪,并運(yùn)用最小作用量原理,是分析力學(xué)的重要組成部分桃笙。經(jīng)典力學(xué)最初的表述形式由牛頓建立氏堤,它著重于分析位移,速度搏明,加速度鼠锈,力等矢量間的關(guān)系,又稱(chēng)為矢量力學(xué)星著。拉格朗日引入了廣義坐標(biāo)的概念购笆,又運(yùn)用達(dá)朗貝爾原理,求得與牛頓第二定律等價(jià)的拉格朗日方程虚循。不僅如此同欠,拉格朗日方程具有更普遍的意義,適用范圍更廣泛邮丰。還有行您,選取恰當(dāng)?shù)膹V義坐標(biāo),可以大大地簡(jiǎn)化拉格朗日方程的求解過(guò)程剪廉。
如圖2所示娃循,建立直角坐標(biāo)系:


圖2 建立直角坐標(biāo)系

求解方法



最后得到的表達(dá)式很長(zhǎng),就不展示了斗蒋。
上面的計(jì)算均在Matlab上完成捌斧,因?yàn)槠溆?jì)算很強(qiáng)大笛质,下面就開(kāi)始用JavaScript來(lái)實(shí)現(xiàn)計(jì)算。
采用四階龍格-庫(kù)塔算法進(jìn)行迭代計(jì)算:



實(shí)現(xiàn)的關(guān)鍵代碼如下:
                        var m1 = this.m1; //帶this的是與輸入綁定的變量
                        var m2 = this.m2;
                        var l1 = this.l1;
                        var l2 = this.l2;
                        var g = this.g;

                        var y1 = [];
                        var y2 = [];
                        var y3 = [];
                        var y4 = [];

                        y1[0] = [0, this.initialTheta1 / 180 * Math.PI]; //迭代初始條件
                        y2[0] = [0, this.initialOmega1 / 180 * Math.PI];
                        y3[0] = [0, this.initialTheta2 / 180 * Math.PI];
                        y4[0] = [0, this.initialOmega2 / 180 * Math.PI];

                        var k1_1 = 0;
                        var k1_2 = 0;
                        var k1_3 = 0;
                        var k1_4 = 0;

                        var k2_1 = 0;
                        var k2_2 = 0;
                        var k2_3 = 0;
                        var k2_4 = 0;

                        var k3_1 = 0;
                        var k3_2 = 0;
                        var k3_3 = 0;
                        var k3_4 = 0;

                        var k4_1 = 0;
                        var k4_2 = 0;
                        var k4_3 = 0;
                        var k4_4 = 0;

                        var h = this.stepLength;
                        var timeRange = this.timeRange;

                        for (var i = 0; i < timeRange / h; i++) {
                            k1_1 = y2[i][1];
                            k1_2 = y2[i][1] + h / 2 * k1_1;
                            k1_3 = y2[i][1] + h / 2 * k1_2;
                            k1_4 = y2[i][1] + h * k1_3;
                            y1[i + 1] = [(i + 1) * h, y1[i][1] + h / 6 * (k1_1 + 2 * k1_2 + 2 * k1_3 + k1_4)];

                            k2_1 = (m2 * Math.cos(y1[i][1] - y3[i][1]) * (g * Math.sin(y3[i][1]) - l1 *
                                Math.sin(y1[i][1] - y3[i][1]) * Math.pow(y2[i][1], 2)) / (l1 * m1 + l1 *
                                m2 - l1 * m2 * Math.pow(Math.cos(y1[i][1] - y3[i][1]), 2)) - (g * Math.sin(
                                    y1[i][1]) * (m1 + m2) + l2 * m2 * Math.sin(y1[i][1] - y3[i][1]) * Math
                                .pow(y4[i][1], 2)) / (l1 * m1 + l1 * m2 - l1 * m2 * Math.pow(Math.cos(
                                y1[i][1] - y3[i][1]), 2)));
                            k2_2 = (m2 * Math.cos((y1[i][1] + h / 2 * k2_1) - (y3[i][1] + h / 2 * k2_1)) * (g *
                                Math.sin(y3[i][1] + h / 2 * k2_1) - l1 * Math.sin((y1[i][1] + h / 2 * k2_1) - (y3[i][1] +
                                    h / 2 * k2_1)) * Math.pow((y2[i][1] + h / 2 * k2_1), 2)) / (l1 * m1 + l1 * m2 -
                                l1 * m2 * Math.pow(Math.cos((y1[i][1] + h / 2 * k2_1) - (y3[i][1] + h / 2 * k2_1)), 2)
                            ) - (g * Math.sin(y1[i][1] + h / 2 * k2_1) * (m1 + m2) + l2 * m2 * Math.sin((
                                y1[i][1] + h / 2 * k2_1) - (y3[i][1] + h / 2 * k2_1)) * Math.pow((y4[i][1] + h / 2 * k2_1),
                                2)) / (l1 * m1 + l1 * m2 - l1 * m2 * Math.pow(Math.cos((y1[i][1] + h /
                                2 * k2_1) - (y3[i][1] + h / 2 * k2_1)), 2)));
                            k2_3 = (m2 * Math.cos((y1[i][1] + h / 2 * k2_2) - (y3[i][1] + h / 2 * k2_2)) * (g *
                                Math.sin(y3[i][1] + h / 2 * k2_2) - l1 * Math.sin((y1[i][1] + h / 2 * k2_2) - (y3[i][1] +
                                    h / 2 * k2_2)) * Math.pow((y2[i][1] + h / 2 * k2_2), 2)) / (l1 * m1 + l1 * m2 -
                                l1 * m2 * Math.pow(Math.cos((y1[i][1] + h / 2 * k2_2) - (y3[i][1] + h / 2 * k2_2)), 2)
                            ) - (g * Math.sin(y1[i][1] + h / 2 * k2_2) * (m1 + m2) + l2 * m2 * Math.sin((
                                y1[i][1] + h / 2 * k2_2) - (y3[i][1] + h / 2 * k2_2)) * Math.pow((y4[i][1] + h / 2 * k2_2),
                                2)) / (l1 * m1 + l1 * m2 - l1 * m2 * Math.pow(Math.cos((y1[i][1] + h /
                                2 * k2_2) - (y3[i][1] + h / 2 * k2_2)), 2)));
                            k2_4 = (m2 * Math.cos((y1[i][1] + h * k2_3) - (y3[i][1] + h * k2_3)) * (g * Math.sin(
                                    y3[i][1] + h * k2_3) - l1 * Math.sin((y1[i][1] + h * k2_3) - (y3[i][1] + h * k2_3)) *
                                Math.pow((y2[i][1] + h * k2_3), 2)) / (l1 * m1 + l1 * m2 - l1 * m2 *
                                Math.pow(Math.cos((y1[i][1] + h * k2_3) - (y3[i][1] + h * k2_3)), 2)) - (g * Math.sin(y1[
                                i][1] + h * k2_3) * (m1 + m2) + l2 * m2 * Math.sin((y1[i][1] + h * k2_3) - (
                                y3[i][1] + h * k2_3)) * Math.pow((y4[i][1] + h * k2_3), 2)) / (l1 * m1 + l1 * m2 -
                                l1 * m2 * Math.pow(Math.cos((y1[i][1] + h * k2_3) - (y3[i][1] + h * k2_3)), 2)));
                            y2[i + 1] = [(i + 1) * h, y2[i][1] + h / 6 * (k2_1 + 2 * k2_2 + 2 * k2_3 + k2_4)];

                            k3_1 = y4[i][1];
                            k3_2 = y4[i][1] + h / 2 * k3_1;
                            k3_3 = y4[i][1] + h / 2 * k3_2;
                            k3_4 = y4[i][1] + h * k3_3;
                            y3[i + 1] = [(i + 1) * h, y3[i][1] + h / 6 * (k3_1 + 2 * k3_2 + 2 * k3_3 + k3_4)];

                            k4_1 = (Math.cos(y1[i][1] - y3[i][1]) * (g * Math.sin(y1[i][1]) * (m1 + m2) +
                                l2 * m2 * Math.sin(y1[i][1] - y3[i][1]) * Math.pow(y4[i][1], 2))) / (l2 *
                                m1 + l2 * m2 - l2 * m2 * Math.pow(Math.cos(y1[i][1] - y3[i][1]), 2)) - (
                                (m1 + m2) * (g * Math.sin(y3[i][1]) - l1 * Math.sin(y1[i][1] - y3[i][1]) *
                                    Math.pow(y2[i][1], 2))) / (l2 * m1 + l2 * m2 - l2 * m2 * Math.pow(Math.cos(
                                y1[i][1] - y3[i][1]), 2));
                            k4_2 = (Math.cos((y1[i][1] + h / 2 * k4_1) - (y3[i][1] + h / 2 * k4_1)) * (g * Math.sin((
                                y1[i][1] + h / 2 * k4_1)) * (m1 + m2) + l2 * m2 * Math.sin((y1[i][1] + h /
                                2 * k4_1) - (y3[i][1] + h / 2 * k4_1)) * Math.pow((y4[i][1] + h / 2 * k4_1), 2))) / (l2 *
                                m1 + l2 * m2 - l2 * m2 * Math.pow(Math.cos((y1[i][1] + h / 2 * k4_1) - (y3[
                                    i][1] + h / 2 * k4_1)), 2)) - ((m1 + m2) * (g * Math.sin((y3[i][1] + h / 2 * k4_1)) -
                                l1 * Math.sin((y1[i][1] + h / 2 * k4_1) - (y3[i][1] + h / 2 * k4_1)) * Math.pow((y2[i]
                                    [1] + h / 2 * k4_1), 2))) / (l2 * m1 + l2 * m2 - l2 * m2 * Math.pow(Math.cos(
                                (y1[i][1] + h / 2 * k4_1) - (y3[i][1] + h / 2 * k4_1)), 2));
                            k4_3 = (Math.cos((y1[i][1] + h / 2 * k4_2) - (y3[i][1] + h / 2 * k4_2)) * (g * Math.sin((
                                y1[i][1] + h / 2 * k4_2)) * (m1 + m2) + l2 * m2 * Math.sin((y1[i][1] + h /
                                2 * k4_2) - (y3[i][1] + h / 2 * k4_2)) * Math.pow((y4[i][1] + h / 2 * k4_2), 2))) / (l2 *
                                m1 + l2 * m2 - l2 * m2 * Math.pow(Math.cos((y1[i][1] + h / 2 * k4_2) - (y3[
                                    i][1] + h / 2 * k4_2)), 2)) - ((m1 + m2) * (g * Math.sin((y3[i][1] + h / 2 * k4_2)) -
                                l1 * Math.sin((y1[i][1] + h / 2 * k4_2) - (y3[i][1] + h / 2 * k4_2)) * Math.pow((y2[i]
                                    [1] + h / 2 * k4_2), 2))) / (l2 * m1 + l2 * m2 - l2 * m2 * Math.pow(Math.cos(
                                (y1[i][1] + h / 2 * k4_2) - (y3[i][1] + h / 2 * k4_2)), 2));
                            k4_4 = (Math.cos((y1[i][1] + h * k4_3) - (y3[i][1] + h * k4_3)) * (g * Math.sin((y1[i]
                                [1] + h * k4_3)) * (m1 + m2) + l2 * m2 * Math.sin((y1[i][1] + h * k4_3) - (y3[
                                i][1] + h * k4_3)) * Math.pow((y4[i][1] + h * k4_3), 2))) / (l2 * m1 + l2 * m2 -
                                l2 * m2 * Math.pow(Math.cos((y1[i][1] + h * k4_3) - (y3[i][1] + h * k4_3)), 2)) - ((
                                m1 + m2) * (g * Math.sin((y3[i][1] + h * k4_3)) - l1 * Math.sin((y1[i][1] +
                                h * k4_3) - (y3[i][1] + h * k4_3)) * Math.pow((y2[i][1] + h * k4_3), 2))) / (l2 * m1 +
                                l2 * m2 - l2 * m2 * Math.pow(Math.cos((y1[i][1] + h * k4_3) - (y3[i][1] + h *
                                    k4_3)), 2));
                            y4[i + 1] = [(i + 1) * h, y4[i][1] + h / 6 * (k4_1 + 2 * k4_2 + 2 * k4_3 + k4_4)];
                        };

                        this.theta1 = y1; //這里最終得到原始數(shù)據(jù)
                        this.omega1 = y2;
                        this.theta2 = y3;
                        this.omega2 = y4;
                        
                        // 由于原始數(shù)據(jù)過(guò)度密集捞蚂,導(dǎo)致繪制曲線困難妇押,下面將繪制曲線的數(shù)據(jù)進(jìn)行稀釋?zhuān)铀倮L圖速度。
                        for(var j = 0; j < this.timeRange/this.stepLength; j += 100){
                            this.roughTheta1.push([j*this.stepLength, this.theta1[j][1]]);
                            this.roughOmega1.push([j*this.stepLength, this.omega1[j][1]]);
                            this.roughTheta2.push([j*this.stepLength, this.theta2[j][1]]);
                            this.roughOmega2.push([j*this.stepLength, this.omega2[j][1]]);
                            
                            this.innerBallPosition[j/100] = [l1 * Math.sin(y1[j][1]), -l1 * Math.cos(y1[j][1])];
                            this.outerBallPosition[j/100] = [l1 * Math.sin(y1[j][1]) + l2 * Math.sin(y3[j][1]), -l1 * Math.cos(y1[j][1]) - l2 * Math.cos(y3[j][1])];
                        };

可能排版很亂姓迅,很多符號(hào)實(shí)在不好打敲霍,就截圖,請(qǐng)諒解丁存。
在線體驗(yàn)連接:點(diǎn)擊在線體驗(yàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肩杈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子解寝,更是在濱河造成了極大的恐慌扩然,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聋伦,死亡現(xiàn)場(chǎng)離奇詭異夫偶,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)觉增,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)兵拢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人抑片,你說(shuō)我怎么就攤上這事卵佛。” “怎么了敞斋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵截汪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我植捎,道長(zhǎng)衙解,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任焰枢,我火速辦了婚禮蚓峦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘济锄。我一直安慰自己暑椰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布荐绝。 她就那樣靜靜地躺著一汽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪低滩。 梳的紋絲不亂的頭發(fā)上召夹,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天岩喷,我揣著相機(jī)與錄音,去河邊找鬼监憎。 笑死纱意,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鲸阔。 我是一名探鬼主播偷霉,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼隶债!你這毒婦竟也來(lái)了腾它?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤死讹,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后曲梗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體赞警,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年虏两,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愧旦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡定罢,死狀恐怖笤虫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情祖凫,我是刑警寧澤琼蚯,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站惠况,受9級(jí)特大地震影響遭庶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稠屠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一峦睡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧权埠,春花似錦榨了、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至秩彤,卻和暖如春叔扼,著一層夾襖步出監(jiān)牢的瞬間事哭,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工瓜富, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鳍咱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓与柑,卻偏偏與公主長(zhǎng)得像谤辜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子价捧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349