iT邦幫忙

0

<html/javastript> function solution 內的值無法傳出

<script>
    var c = document.getElementById("bar"); //畫在名為"bar"的容器之中
    var ctx = c.getContext("2d");
    var ctx1 = c.getContext("2d");
    var ctx2 = c.getContext("2d");
    var ctx3 = c.getContext("2d");
    var ctx4 = c.getContext("2d"); //繪製2d圖型

    var sp1, ep1, sp2, ep2, sp3, ep3, sp4, ep4; //定一點爲起始點 //定一點爲終點
    var l1 = 300,
        l2 = 100,
        l3 = 300,
        l4 = 150; //給定桿長(300,100,300,150)
    var t1 = 0,
        t2 = 1.05,
        t3 = 0.18137,
        t4 = 1.2314203; //給定初始角度(弧度制)(0,1.05)
    var dt2 = 0.005; //給定每次的角變化量(弧度制),不知道為什麼只要速度超過這個值l3的長度就會有變化
    var dt3, dt4; //變數
    var e1, e2; //變數
    var i;
    var e = 0.01;
    var flag = 0;
    var v1, v2, v3, v4;
    var a1, a2, a3, a4;

    var os, os1; //定一變數用來控制開關

    flag = 0;
    do {
        e1 = l2 * Math.cos(t2) + l3 * Math.cos(t3) - l4 * Math.cos(t4) - l1;
        e2 = l2 * Math.sin(t2) + l3 * Math.sin(t3) - l4 * Math.sin(t4);
        dt3 = (e1 * Math.cos(t4) + e2 * Math.sin(t4)) / (l3 * Math.sin(t3 - t4));
        dt4 = (e1 * Math.cos(t3) + e2 * Math.sin(t3)) / (l4 * Math.sin(t3 - t4));
        t4 = t4 + dt4;
        t3 = t3 + dt3;
        if (Math.abs(dt3) < e && Math.abs(dt4) < e)
            flag = 1;
    }
    while (flag == 0);

    function origin() { //寫一個在視窗初始之時,顯示一條線段的程式

        ctx.clearRect(0, 0, bar.width, bar.height); //在畫新的一格前清空版面

        sp1 = {
            x: 250,
            y: 250
        }; //定起始點的xy軸位置 (250,250)
        ep1 = {
            x: 550,
            y: 250
        }; //定終點的xy軸位置(550,250)
        ctx1.lineWidth = 1; //線寬
        ctx1.strokeStyle = "red"; //線色
        ctx1.beginPath(); //要畫多次圖形時要給定此行
        ctx1.moveTo(sp1.x, sp1.y); //設定線段的起始點
        ctx1.lineTo(ep1.x, ep1.y); //設定線段的終點
        ctx1.stroke(); //開始繪製

        sp2 = {
            x: 250,
            y: 250
        }; //(250,250)
        ep2 = {
            x: sp2.x + l2 * Math.cos(t2),
            y: sp2.y - l2 * Math.sin(t2)
        }; //定終點的xy軸位
        ctx2.lineWidth = 1; //線寬
        ctx2.strokeStyle = "yellow";
        ctx2.beginPath(); //要畫多次圖形時要給定此行
        ctx2.moveTo(sp2.x, sp2.y); //設定線段的起始點
        ctx2.lineTo(ep2.x, ep2.y); //設定線段的終點
        ctx2.stroke(); //開始繪製

        sp4 = {
            x: 550,
            y: 250
        }; //定起始點的xy軸位置
        ep4 = {
            x: sp4.x + l4 * Math.cos(t4),
            y: sp4.y - l4 * Math.sin(t4)
        }; //定終點的xy軸位置
        ctx4.lineWidth = 1; //線寬
        ctx4.strokeStyle = "blue"; //線色
        ctx4.beginPath(); //要畫多次圖形時要給定此行
        ctx4.moveTo(sp4.x, sp4.y); //設定線段的起始點
        ctx4.lineTo(ep4.x, ep4.y); //設定線段的終點
        ctx4.stroke(); //開始繪製

        sp3 = {
            x: ep2.x,
            y: ep2.y
        }; //定起始點的xy軸位置
        ep3 = {
            x: ep4.x,
            y: ep4.y
        }; //定終點的xy軸位置
        ctx3.lineWidth = 1; //線寬
        ctx3.strokeStyle = "green"; //線色
        ctx3.beginPath(); //要畫多次圖形時要給定此行
        ctx3.moveTo(sp3.x, sp3.y); //設定線段的起始點
        ctx3.lineTo(ep3.x, ep3.y); //設定線段的終點
        ctx3.stroke(); //開始繪製

    }

    function rotate() { //寫一個用於繪製旋轉後圖形的程式

        flag = 0;
        do {
            e1 = l2 * Math.cos(t2) + l3 * Math.cos(t3) - l4 * Math.cos(t4) - l1;
            e2 = l2 * Math.sin(t2) + l3 * Math.sin(t3) - l4 * Math.sin(t4);
            dt3 = (e1 * Math.cos(t4) + e2 * Math.sin(t4)) / (l3 * Math.sin(t3 - t4));
            dt4 = (e1 * Math.cos(t3) + e2 * Math.sin(t3)) / (l4 * Math.sin(t3 - t4));
            t4 = t4 + dt4;
            t3 = t3 + dt3;
            if (Math.abs(dt3) < e && Math.abs(dt4) < e)
                flag = 1;
        }
        while (flag == 0);

        ctx.clearRect(0, 0, bar.width, bar.height); //在畫新的一格前清空版面

        sp1 = {
            x: 250,
            y: 250
        }; //定起始點的xy軸位置 (250,250)
        ep1 = {
            x: 550,
            y: 250
        }; //定終點的xy軸位置(550,250)
        ctx1.lineWidth = 1; //線寬
        ctx1.strokeStyle = "red"; //線色
        ctx1.beginPath(); //要畫多次圖形時要給定此行
        ctx1.moveTo(sp1.x, sp1.y); //設定線段的起始點
        ctx1.lineTo(ep1.x, ep1.y); //設定線段的終點
        ctx1.stroke(); //開始繪製

        t2 = t2 + dt2;
        sp2 = {
            x: 250,
            y: 250
        }; //(250,250)
        ep2 = {
            x: sp2.x + l2 * Math.cos(t2),
            y: sp2.y - l2 * Math.sin(t2)
        }; //定終點的xy軸位
        ctx2.lineWidth = 1; //線寬
        ctx2.strokeStyle = "yellow";
        ctx2.beginPath(); //要畫多次圖形時要給定此行
        ctx2.moveTo(sp2.x, sp2.y); //設定線段的起始點
        ctx2.lineTo(ep2.x, ep2.y); //設定線段的終點
        ctx2.stroke(); //開始繪製

        sp4 = {
            x: 550,
            y: 250
        }; //定起始點的xy軸位置
        ep4 = {
            x: sp4.x + l4 * Math.cos(t4),
            y: sp4.y - l4 * Math.sin(t4)
        }; //定終點的xy軸位置
        ctx4.lineWidth = 1; //線寬
        ctx4.strokeStyle = "blue"; //線色
        ctx4.beginPath(); //要畫多次圖形時要給定此行
        ctx4.moveTo(sp4.x, sp4.y); //設定線段的起始點
        ctx4.lineTo(ep4.x, ep4.y); //設定線段的終點
        ctx4.stroke(); //開始繪製

        sp3 = {
            x: ep2.x,
            y: ep2.y
        }; //定起始點的xy軸位置
        ep3 = {
            x: ep4.x,
            y: ep4.y
        }; //定終點的xy軸位置
        ctx3.lineWidth = 1; //線寬
        ctx3.strokeStyle = "green"; //線色
        ctx3.beginPath(); //要畫多次圖形時要給定此行
        ctx3.moveTo(sp3.x, sp3.y); //設定線段的起始點
        ctx3.lineTo(ep3.x, ep3.y); //設定線段的終點
        ctx3.stroke(); //開始繪製

        document.getElementById("ep2.x").innerHTML = Math.round(ep2.x); //抓取桿件末端點的X位置,並賦予其id"epx"
        document.getElementById("ep2.y").innerHTML = Math.round(ep2.y); //抓取桿件末端點的Y位置,並賦予其id"epy"
        document.getElementById("ep3.x").innerHTML = Math.round(ep3.x);
        document.getElementById("ep3.y").innerHTML = Math.round(ep3.y);
        document.getElementById("l4").innerHTML = Math.round(Math.sqrt(Math.pow((ep4.x - sp4.x), 2) + Math.pow((ep4.y - sp4.y), 2)));
        document.getElementById("l3").innerHTML = Math.round(Math.sqrt(Math.pow((ep3.x - sp3.x), 2) + Math.pow((ep3.y - sp3.y), 2)));
        document.getElementById("t4").innerHTML = Math.floor(t4);

        //document.getElementById("v1").innerHTML = Math.PI(Math.);
        // document.getElementById("v2").innerHTML = Math.PI(v2);
        // document.getElementById("v3").innerHTML = Math.PI(v3);
        // document.getElementById("t2").innerHTML = Math.PI(t2);
        // document.getElementById("t3").innerHTML = Math.PI(t3);
        // document.getElementById("t4").innerHTML = Math.PI(t4);
    }

    *function solution()* {

        var l1 = 300,
            l2 = 100,
            l3 = 300,
            l4 = 150; //給定桿長(300,100,300,150)
        var t1,
            t2 = 1.05,
            t3,
            t4; //給定初始角度(弧度制)(0,1.05)
        var dt2 = 0.005; //給定每次的角變化量(弧度制),不知道為什麼只要速度超過這個值l3的長度就會有變化
        var dt3, dt4; //變數
        var e1, e2; //變數
        var i;
        var e = 0.0001;
        var flag = 0;
        var a1, a2, a3, a4;

        flag = 0;
        do {
            e1 = l2 * Math.cos(t2) + l3 * Math.cos(t3) - l4 * Math.cos(t4) - l1;
            e2 = l2 * Math.sin(t2) + l3 * Math.sin(t3) - l4 * Math.sin(t4);
            dt3 = (e1 * Math.cos(t4) + e2 * Math.sin(t4)) / (l3 * Math.sin(t3 - t4));
            dt4 = (e1 * Math.cos(t3) + e2 * Math.sin(t3)) / (l4 * Math.sin(t3 - t4));
            t4 = t4 + dt4;
            t3 = t3 + dt3;
            if (Math.abs(dt3) < e && Math.abs(dt4) < e)
                flag = 1;
        }
        while (flag == 0);


        t2 = t2 + dt2
        sp2 = {
            x: 250,
            y: 250
        }; //(250,250)
        ep2 = {
            x: sp2.x + l2 * Math.cos(t2),
            y: sp2.y - l2 * Math.sin(t2)
        }; //定終點的xy軸位

        var v1, v2, v3, v4;
        var u = (-l3 * Math.sin(t3));
        var v = l4 * Math.sin(t4);
        var w = l2 * Math.sin(t2);
        var x = l3 * Math.cos(t3);
        var y = (-l4 * Math.cos(t4));
        var z = (-l2 * Math.cos(t2));
        var v2 = (l2 * dt2 * 20); //速度=R*ω,ω=dθ/dt=dt2/50(毫秒-秒*1000)
        var v3 = (w * x - u * z) / (v * x - u * y);

        document.getElementById("v2").innerHTML = Math.PI(v2);
        document.getElementById("v3").innerHTML = Math.PI(v3);
        document.getElementById("t2").innerHTML = Math.PI(t2);
        document.getElementById("t3").innerHTML = Math.PI(t3);
        document.getElementById("t4").innerHTML = Math.PI(t4);

    }

    function start() { //指示開始旋轉的程式
        os = setInterval(rotate, 50); //setInterval括弧內,前項爲欲執行的程式,後項爲多少毫秒執行該程式一次

    }

    function pause() { //指示暫停旋轉的程式
        clearInterval(os); //要是剛剛setInterval那沒有設定一個值(os)來控制開關的話,這邊會關不起來


    }

    origin(); //告知程式在視窗一開始之時就執行"origin"
</script>

<table border="2">
    <tr>

        <td colspan="4" width="480px">監控式</td>
    </tr>

    <tr>

        <td width="120px">EPx.2:</td>

        <td width="120px" id="ep2.x"></td>
        <!--在表格這格放入id"epx"的資料-->

        <td width="120px">EPy.2:</td>

        <td width="120px" id="ep2.y"></td>
        <!--在表格這格放入id"epy"的資料-->
    </tr>
    <tr>
        <td width="120px">EPx.3:</td>
        <td width="120px" id="ep3.x"></td>
        <!--在表格這格放入id"epx"的資料-->
        <td width="120px">EPy.3:</td>
        <td width="120px" id="ep3.y"></td>
    </tr>
    <tr>
        <td width="120px">l4:</td>

        <td width="120px" id="l4"></td>
        <td width="120px">l3:</td>

        <td width="120px" id="l3"></td>
    </tr>
    <tr>
        <td width="120px">t2:</td>
        <td width="120px" id="t2"></td>
        <td width="120px">t3:</td>
        <td width="120px" id="t3"></td>
        <td width="120px">t4:</td>
        <td width="120px" id="t4"></td>
    </tr>
    <tr>
        <td width="120px">v2:</td>
        <td width="120px" id="v2"></td>
        <td width="120px">v3:</td>
        <td width="120px" id="v3"></td>
    </tr>

</table>

<button type="button" onclick="start()" style="position: absolute; top:600px;left:600px; width:90px;">
    Start
</button>
<!--設置一個用來啟動的按鈕-->

<button type="button" onclick="pause()" style="position: absolute; top:630px;left:600px; width:90px;">
    Pause
</button>
<!--設置一個用來暫停的按鈕-->

https://ithelp.ithome.com.tw/upload/images/20191230/20123966d9VXom5O7X.png
跑出來的程式大概長這樣
我有嘗試讓 solution 放進去跑
function start() { //指示開始旋轉的程式
os = setInterval(rotate, 50);
os1 = setInterval(solution, 50);
}

function pause() {
clearInterval(os);
clearInterval(os1);
}
function pause() {
clearInterval(os);
clearInterval(os1);
}
可是最後直接無法跑

看更多先前的討論...收起先前的討論...
看不懂你要問什麼
你這段程式碼沒有執行 solution 這個 function
----
你要看一下你的變數的問題導致無窮迴圈

你可以用F12 的中斷點或寫 debugger;
淺水員 iT邦新手 1 級 ‧ 2019-12-30 17:40:51 檢舉
這邊求解可以直接用數學的方法去算兩圓交點,不需要用迴圈求解。
ccutmis iT邦高手 8 級 ‧ 2019-12-30 17:48:40 檢舉
類似這種效果嗎?
http://www.web3d.url.tw/demo/USER/css_demo/css3d-tester/view/
fillano iT邦超人 1 級 ‧ 2019-12-30 17:58:18 檢舉
先檢查一下solution函數裡面的do while迴圈,程式無法離開迴圈。這樣會讓你cpu一直滿載吧XD,而且因為solution函數沒執行完,使得其他函數不會跑,程式就停擺了。
fillano iT邦超人 1 級 ‧ 2019-12-30 18:19:33 檢舉
我沒在看你再做什麼,不過把solution開頭變數宣告那一段刪光光,然後把Math.PI(xx)那幾行改成Math.PI * xx的話是會動的。

2 個回答

1
小魚
iT邦大師 1 級 ‧ 2019-12-30 17:23:46

為什麼你的 solution 前後多了 * ?

fillano iT邦超人 1 級 ‧ 2019-12-30 18:05:43 檢舉

我猜只是為了讓我們看清楚solution在哪裡XD

2
淺水員
iT邦新手 1 級 ‧ 2019-12-30 18:30:39

先給 code (這是直接用數學的方法求解)
index.html

<!DOCTYPE html>
<html lang="Zh-Hant">
<head>
	<meta charset="utf-8">
	<title>demo</title>
</head>
<body>
	<canvas id="bar" width="1000" height="600"></canvas>
	<button onclick="start()">Start</button>
	<button onclick="pause()">Pause</button>
	<script src="main.js"></script>
</body>
</html>

main.js

var c = document.getElementById("bar"); //畫在名為"bar"的容器之中
var ctx = c.getContext("2d");

function drawImg(theta) {
	
	ctx.clearRect(0, 0, bar.width, bar.height);
	
	var p0={ //左下的點
		x:250,
		y:250
	}
	var p1={ //右下的點
		x:550,
		y:250
	}
	var p2={ //左上的點
		x:p0.x+100*Math.cos(theta),
		y:p0.y+100*Math.sin(theta)
	}
	var v1={ //向量,p2 指向 p1
		x:p1.x-p2.x,
		y:p1.y-p2.y
	}
	v1.len=Math.sqrt(v1.x*v1.x+v1.y*v1.y);
	var v2={ //以 v1 為新的 x 軸,計算 p3 的 x,y
		x:(300*300+v1.len*v1.len-150*150)/(2*v1.len)
	}
	v2.y=Math.sqrt(300*300-v2.x*v2.x);
	var p3={ //右上的點
		x:p2.x+(v2.x*v1.x-v2.y*v1.y)/v1.len,
		y:p2.y+(v2.x*v1.y+v2.y*v1.x)/v1.len
	}
		
	ctx.lineWidth = 1; //線寬
	ctx.strokeStyle = "red"; //線色
	ctx.beginPath(); //要畫多次圖形時要給定此行
	ctx.moveTo(p0.x, 500-p0.y); //設定線段的起始點
	ctx.lineTo(p1.x, 500-p1.y); //設定線段的終點
	ctx.stroke(); //開始繪製

	ctx.strokeStyle = "yellow";
	ctx.beginPath();
	ctx.moveTo(p0.x, 500-p0.y);
	ctx.lineTo(p2.x, 500-p2.y);
	ctx.stroke();
	
	ctx.strokeStyle = "green";
	ctx.beginPath();
	ctx.moveTo(p3.x, 500-p3.y);
	ctx.lineTo(p1.x, 500-p1.y);
	ctx.stroke();

	ctx.strokeStyle = "blue";
	ctx.beginPath();
	ctx.moveTo(p3.x, 500-p3.y);
	ctx.lineTo(p2.x, 500-p2.y);
	ctx.stroke();
}

var theta=Math.PI/2;
var dtheta=Math.PI/50;
function rotate() { //寫一個用於繪製旋轉後圖形的程式
	drawImg(theta+=dtheta);
}

function start() { //指示開始旋轉的程式
	os = setInterval(rotate, 40); //setInterval括弧內,前項爲欲執行的程式,後項爲多少毫秒執行該程式一次
}

function pause() { //指示暫停旋轉的程式
	clearInterval(os); //要是剛剛setInterval那沒有設定一個值(os)來控制開關的話,這邊會關不起來
}

drawImg(theta); //告知程式在視窗一開始之時就執行"drawImg"

我要發表回答

立即登入回答