• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

              C++博客 :: 首頁(yè) :: 聯(lián)系 ::  :: 管理
              163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(48)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            積分與排名

            • 積分 - 401319
            • 排名 - 59

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜



            在這個(gè)教程里我們將模擬一段繩索,我們是在39課的基礎(chǔ)上進(jìn)行的。

            在物理模擬中,我們必須設(shè)置各個(gè)物理量,就像它們?cè)谧匀唤缰械男袨橐粯印DM中的運(yùn)動(dòng)并不一定和自然界相同,我們使用的運(yùn)動(dòng)模型,必須和我們需要模擬的目的有關(guān),目的決定了它的精確度。要知道我們的目標(biāo)不是模擬原子和分子,也不是模擬成千上萬(wàn)的粒子系。首先我們需要確定我們模擬的目標(biāo),才能創(chuàng)建我們的物理模型。它和下面內(nèi)容相關(guān):

            1. 運(yùn)動(dòng)的數(shù)學(xué)表示
            2. 執(zhí)行模擬的計(jì)算機(jī)的速度

            1. 運(yùn)動(dòng)的數(shù)學(xué)表示:

            這個(gè)問(wèn)題決定了我們使用何種數(shù)學(xué)方程來(lái)模擬運(yùn)動(dòng),使用經(jīng)典力學(xué)還是量子力學(xué)。

            2. 執(zhí)行模擬的計(jì)算機(jī)的速度:

            計(jì)算機(jī)的速度決定了我們可以模擬的精度。

            設(shè)計(jì)繩索的物理模型:

            我們?cè)诮?jīng)典力學(xué)和高于500Mhz的計(jì)算機(jī)上模擬這個(gè)問(wèn)題。首先我們需要設(shè)定需要的精度,我們使用一系列互相用彈簧連接的質(zhì)點(diǎn)來(lái)模擬繩索,精度決定了我們用多少個(gè)點(diǎn)來(lái)模擬,當(dāng)然越多越精確。在下面我決定用50或100個(gè)點(diǎn)來(lái)模擬繩子一段3或4m長(zhǎng)的繩子,換句話說(shuō),我們的模擬精度就是3到8厘米。

            設(shè)計(jì)運(yùn)動(dòng)模型:

            在繩子中,施加給各個(gè)質(zhì)點(diǎn)的力來(lái)自于自身的質(zhì)量和相連的內(nèi)力(參見(jiàn)大學(xué)里的普通力學(xué))。如下我們用"O"表示質(zhì)點(diǎn),“—”表示連接質(zhì)點(diǎn)的彈簧。
            O----O----O----O
            1 2 3 4

            彈簧的力學(xué)公式如下:

            力 = -k * x
            k: 彈性系數(shù)
            x: 相距平衡位置的位移

            上面的公式說(shuō)明,如果相鄰點(diǎn)的距離為平衡距離,那么它們不受到任何力的作用。如果我們?cè)O(shè)置平衡位置為5cm,那么100個(gè)點(diǎn)的繩子長(zhǎng)5m。如果相連質(zhì)點(diǎn)之間的位置小于5cm,它們受到排斥力。

            上面的公式只是一個(gè)基礎(chǔ),現(xiàn)在我們可以加上摩擦力,如果沒(méi)有這項(xiàng),那么繩子將永遠(yuǎn)動(dòng)下去。

            彈簧類:

            這個(gè)類包含相連接的兩個(gè)物體,它們之間具有作用力。



            class Spring
            {
            public:
            Mass* mass1; // 質(zhì)點(diǎn)1
            Mass* mass2; // 質(zhì)點(diǎn)2

            float springConstant; // 彈性系數(shù)
            float springLength; //彈簧長(zhǎng)度
            float frictionConstant; //摩擦系數(shù)

            Spring(Mass* mass1, Mass* mass2,
            // 構(gòu)造函數(shù)
            float springConstant, float springLength, float frictionConstant)
            {
            this->springConstant = springConstant;
            this->springLength = springLength;
            this->frictionConstant = frictionConstant;

            this->mass1 = mass1;
            this->mass2 = mass2;
            }

            void solve() // 計(jì)算各個(gè)物體的受力
            {
            Vector3D springVector = mass1->pos - mass2->pos;

            float r = springVector.length(); // 計(jì)算兩個(gè)物體之間的距離

            Vector3D force;

            if (r != 0) // 計(jì)算力
            force += -(springVector / r) * (r - springLength) * springConstant;
            ...

            force += -(mass1->vel - mass2->vel) * frictionConstant; // 加上摩擦力
            mass1->applyForce(force); // 給物體1施加力
            mass2->applyForce(-force); // 給物體2施加力
            }

            下面我們把繩子釘在墻上,所以我們的模擬就多了一個(gè)萬(wàn)有引力,空氣摩擦力。萬(wàn)有引力的公式如下:

            力 = (重力加速度) * 質(zhì)量

            萬(wàn)有引力會(huì)作用在每一個(gè)質(zhì)點(diǎn)上,地面也會(huì)給每個(gè)物體一個(gè)作用力。在我們的模型中將考慮繩子和地面之間的接觸,地面給繩子向上的力,并提供摩擦力。

            設(shè)置模擬的初始值

            現(xiàn)在我們已經(jīng)設(shè)置好模擬環(huán)境了,長(zhǎng)度單位是m,時(shí)間單位是秒,質(zhì)量單位是kg。

            為了設(shè)置初始值,我們必須提供供模擬開(kāi)始的參數(shù)。我們定義一下參數(shù):

            1. 重力加速度: 9.81 m/s/s 垂直向下
            2. 質(zhì)點(diǎn)個(gè)數(shù): 80
            3. 相連質(zhì)點(diǎn)的距離: 5 cm (0.05 meters)
            4. 質(zhì)量: 50 克(0.05 kg)
            5. 繩子開(kāi)始處于垂直狀態(tài)

            下面計(jì)算繩子受到的力

            f = (繩子質(zhì)量) * (重力加速度) = (4 kg) * (9.81) ~= 40 N

            彈簧必須平衡這個(gè)力 40 N,它伸長(zhǎng)1cm,計(jì)算彈性系數(shù):

            合力= -k * x = -k * 0.01 m

            合力應(yīng)該為0 :

            40 N + (-k * 0.01 meters) = 0

            彈性系數(shù) k 為:

            k = 4000 N / m

            設(shè)置彈簧的摩擦系數(shù):

            springFrictionConstant = 0.2 N/(m/s)

            下面我們看看這個(gè)繩索類:

            1. virtual void init() ---> 重置力

            2. virtual void solve() ---> 計(jì)算各個(gè)質(zhì)點(diǎn)的力

            3. virtual void simulate(float dt) ---> 模擬一次

            4. virtual void operate(float dt) ---> 執(zhí)行一次操作

            繩索類如下所示 :


            class RopeSimulation : public Simulation //繩索類
            {
            public:
            Spring** springs; // 彈簧類結(jié)構(gòu)的數(shù)組的指針

            Vector3D gravitation; // 萬(wàn)有引力

            Vector3D ropeConnectionPos; // 繩索的連接點(diǎn)

            Vector3D ropeConnectionVel; //連接點(diǎn)的速度,我們使用這個(gè)移動(dòng)繩子

            float groundRepulsionConstant; //地面的反作用力

            float groundFrictionConstant; //地面的摩擦系數(shù)

            float groundAbsorptionConstant; //地面的緩沖力

            float groundHeight; //地面高度

            float airFrictionConstant; //空氣的摩擦系數(shù)

            下面是它的構(gòu)造函數(shù)


            RopeSimulation(
            int numOfMasses,
            float m,
            float springConstant,
            float springLength,
            float springFrictionConstant,
            Vector3D gravitation,
            float airFrictionConstant,
            float groundRepulsionConstant,
            float groundFrictionConstant,
            float groundAbsorptionConstant,
            float groundHeight
            ) : Simulation(numOfMasses, m)
            {
            this->gravitation = gravitation;

            this->airFrictionConstant = airFrictionConstant;

            this->groundFrictionConstant = groundFrictionConstant;
            this->groundRepulsionConstant = groundRepulsionConstant;
            this->groundAbsorptionConstant = groundAbsorptionConstant;
            this->groundHeight = groundHeight;

            for (int a = 0; a < numOfMasses; ++a) // 設(shè)置質(zhì)點(diǎn)位置
            {
            masses[a]->pos.x = a * springLength;
            masses[a]->pos.y = 0;
            masses[a]->pos.z = 0;
            }

            springs = new Spring*[numOfMasses - 1];

            for (a = 0; a < numOfMasses - 1; ++a) //創(chuàng)建各個(gè)質(zhì)點(diǎn)之間的模擬彈簧
            {
            springs[a] = new Spring(masses[a], masses[a + 1],
            springConstant, springLength, springFrictionConstant);
            }
            }


            計(jì)算施加給各個(gè)質(zhì)點(diǎn)的力


            void solve() // 計(jì)算施加給各個(gè)質(zhì)點(diǎn)的力
            {
            for (int a = 0; a < numOfMasses - 1; ++a) // 彈簧施加給各個(gè)物體的力
            {
            springs[a]->solve();
            }

            for (a = 0; a < numOfMasses; ++a) // 計(jì)算各個(gè)物體受到的其它的力
            {
            masses[a]->applyForce(gravitation * masses[a]->m); // 萬(wàn)有引力
            // 空氣的摩擦力
            masses[a]->applyForce(-masses[a]->vel * airFrictionConstant);

            if (masses[a]->pos.y < groundHeight) // 計(jì)算地面對(duì)質(zhì)點(diǎn)的作用
            {
            Vector3D v;

            v = masses[a]->vel; // 返回速度
            v.y = 0; // y方向的速度為0

            // 計(jì)算地面給質(zhì)點(diǎn)的力
            masses[a]->applyForce(-v * groundFrictionConstant);

            v = masses[a]->vel;
            v.x = 0;
            v.z = 0;

            if (v.y < 0) // 計(jì)算地面的緩沖力

            masses[a]->applyForce(-v * groundAbsorptionConstant);

            // 計(jì)算地面的反作用力
            Vector3D force = Vector3D(0, groundRepulsionConstant, 0) *
            (groundHeight - masses[a]->pos.y);

            masses[a]->applyForce(force); // 施加地面對(duì)質(zhì)點(diǎn)的力
            }
            }
            }


            下面的代碼完成整個(gè)模擬過(guò)程


            void simulate(float dt) // 模擬一次
            {
            Simulation::simulate(dt); // 調(diào)用基類的模擬函數(shù)

            ropeConnectionPos += ropeConnectionVel * dt; // 計(jì)算繩子的連接點(diǎn)

            if (ropeConnectionPos.y < groundHeight)
            {
            ropeConnectionPos.y = groundHeight;
            ropeConnectionVel.y = 0;
            }

            masses[0]->pos = ropeConnectionPos; // 更新繩子的連接點(diǎn)和速度
            masses[0]->vel = ropeConnectionVel;
            }

            void setRopeConnectionVel(Vector3D ropeConnectionVel)
            {
            this->ropeConnectionVel = ropeConnectionVel;
            }


            有了上面的類,我們可以很方便的模擬繩子,代碼如下:


            RopeSimulation* ropeSimulation =
            new RopeSimulation(
            80, // 80 質(zhì)點(diǎn)
            0.05f, // 每個(gè)質(zhì)點(diǎn)50g
            10000.0f, // 彈性系數(shù)
            0.05f, // 質(zhì)點(diǎn)之間的距離
            0.2f, // 彈簧的內(nèi)摩擦力
            Vector3D(0, -9.81f, 0), // 萬(wàn)有引力
            0.02f, // 空氣摩擦力
            100.0f, // 地面反作用系數(shù)
            0.2f, // 地面摩擦系數(shù)
            2.0f, // 地面緩沖系數(shù)
            -1.5f); // 地面高度


            下面的代碼在程序中執(zhí)行繩子的模擬


            float dt = milliseconds / 1000.0f; // 經(jīng)過(guò)的秒數(shù)

            float maxPossible_dt = 0.002f; // 模擬間隔

            int numOfIterations = (int)(dt / maxPossible_dt) + 1; // 模擬次數(shù)
            if (numOfIterations != 0)
            dt = dt / numOfIterations;

            for (int a = 0; a < numOfIterations; ++a) // 執(zhí)行模擬
            ropeSimulation->operate(dt);


             

            我相信這一個(gè)教會(huì)了你很多,從最開(kāi)始的模型的建立,到完成最后的代碼。有了這個(gè)基礎(chǔ),相信你會(huì)創(chuàng)造出很多更有意思的代碼!


            posted on 2007-12-30 15:34 sdfasdf 閱讀(895) 評(píng)論(0)  編輯 收藏 引用 所屬分類: OPENGL
            久久精品亚洲AV久久久无码| 久久精品国产黑森林| 久久精品国产亚洲av日韩| av午夜福利一片免费看久久| 久久婷婷久久一区二区三区| 久久精品无码免费不卡| 亚洲va国产va天堂va久久| 久久久青草久久久青草| 亚洲欧美精品一区久久中文字幕| 伊人久久精品无码二区麻豆| 99久久人妻无码精品系列蜜桃| 亚洲国产精品无码久久久久久曰| 蜜臀久久99精品久久久久久小说| 久久国产成人精品国产成人亚洲| 亚洲色欲久久久综合网东京热| 久久国产一片免费观看| 国产69精品久久久久777| 7777精品伊人久久久大香线蕉| 一本色道久久88加勒比—综合| 久久亚洲国产精品成人AV秋霞| 精品久久久久久无码人妻热| 国产成人综合久久综合| 亚洲熟妇无码另类久久久| 亚洲国产一成久久精品国产成人综合| 久久久噜噜噜久久熟女AA片| 久久久精品波多野结衣| 久久久青草青青亚洲国产免观| 久久久久亚洲精品天堂| 亚洲精品无码久久久久久| 精品综合久久久久久98| 中文字幕亚洲综合久久菠萝蜜| 国产精品美女久久久久AV福利| 99久久精品免费看国产| 狠狠精品干练久久久无码中文字幕| 国产精品久久一区二区三区| 97r久久精品国产99国产精| 久久久精品2019免费观看| 久久久久久久久久久久中文字幕| 久久婷婷国产综合精品| 国产精品久久久久影院色| 伊人久久大香线蕉精品|