2011年5月18日 星期三

三隻小豬的房子--Box2DJS物理引擎測試

不久前Jimmy請我說三隻小豬的故事,記得他還沒讀幼稚園時,晚上為了讓他快點睡覺,三隻小豬的故事我都會把故事情節拖長,為了催出Jimmy的睡意,講大野狼的吹房子的動作也會重複再重複,只不過這次這招沒效了,故事才講到大野狼吹倒豬大哥的房子,Jimmy蹦出句話,"大野狼的廢話怎麼那麼多",我愣了幾秒鐘,心想這小子真的長大了.....
最近在測Box2DJS物理引擎,想到那天晚上那段話,我想大野狼也該隨著時代進步了,學學灰太郎發明氣象武器對付喜羊羊,於是將大野狼遙控烏雲下冰雹攻擊三隻小豬的房子的情節,寫進測試裡
測試中......
按滑鼠左鍵就會產生冰雹

2011年5月16日 星期一

積木作品--Jimmy & Jimmy's Uncle的積木戰機

Jimmy這台戰機組了好幾天,一直看他抱著積木盒上樓下樓修修改改,每組到一個階段,就跟我報告他的戰機新增強化了哪些功能(雖然在我眼中只是多了幾塊積木),還問我要不要拍照放在網路上讓大家欣賞,我就要他繼續強化改版,晚上Jimmy喝睡前的牛奶時,剛好童心未泯的叔叔正在給Jimmy的戰機做修改,於是要求Jimmy的叔叔也順便拍幾張成品照,擺在部落格裡讓大家欣賞
寄件者 scratchlab

寄件者 scratchlab

寄件者 scratchlab

2011年5月11日 星期三

以HTML5畫CropCircle--clip() & CCS3 Rotate特效

這是今年五月份第一個出現的麥田圈,正確來說應該叫"油菜田圈",其實上個月英國已經出現幾個麥田圈了,只不過Jimmy's papa覺得那幾個圈圈怪怪的找不到"對稱性",所以就沒拿來當作HTML5練習,剛好這個油菜田圈找得到"對稱性"蠻適合以程式繪製,也順便測測CCS3 Rotate特效
Your browser does not support the canvas element.

<style type="text/css">
#CCDiv {
  width: 600px;
  height: 430px;
  float: left;
  transform: rotate(5deg);
  -o-transform: rotate(5deg);
  -moz-transform: rotate(5deg);
  -webkit-transform: rotate(5deg);
}
</style>
<div id="CCDiv">
<canvas id="myCropCircle0511" width="600" height="430" style="border:0px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
</div>
<script type="text/javascript">
<!--



function drawTriCircles(context,centerX,centerY,radius,d)
{
    context.save();


    //-----------
    context.fillStyle="black";
    context.globalCompositeOperation = 'xor';
    context.beginPath();
    context.arc(300,150,150,0,Math.PI*2,true);
    context.fill();
    context.globalCompositeOperation = 'xor';
    context.beginPath();
    context.arc(300-75,150+129.9,150,0,Math.PI*2,true);
    context.fill();
    context.globalCompositeOperation = 'xor';
    context.beginPath();
    context.arc(300+75,150+129.9,150,0,Math.PI*2,true);
    context.fill();

    //-----------
    context.beginPath();
    context.arc(300,150,75,0,Math.PI*2,true);

    context.lineWidth=5;
    context.strokeStyle="white"; 
    context.stroke();

    context.beginPath();
    context.arc(300-75,150+129.9,75,0,Math.PI*2,true);

    context.lineWidth=5;
    context.strokeStyle="white"; 
    context.stroke();

    context.beginPath();
    context.arc(300+75,150+129.9,75,0,Math.PI*2,true);

    context.lineWidth=5;
    context.strokeStyle="white"; 
    context.stroke();
    //-----------
    context.restore();
}

function drawAnotherLayerTriCircles(context,centerX,centerY,radius,d)
{
    context.save();

    // Create a circular clipping path  
    context.fillStyle="white";

    context.beginPath();
    context.arc(300,150,150,Math.PI/3*2,Math.PI/3,true);

    context.arc(300-75,150+129.9,150,0,Math.PI/3*5,true);

    context.arc(300+75,150+129.9,150,Math.PI/3*4,Math.PI/3*3,true);

    context.closePath();
    context.fill();
    context.clip();

    context.fillStyle="black";
    context.beginPath();
    context.arc(150,150,150,0,Math.PI*2,true);
    context.fill();
    context.beginPath();
    context.arc(450,150,150,0,Math.PI*2,true);
    context.fill();
    context.beginPath();
    context.arc(300,410,150,0,Math.PI*2,true);
    context.fill();
    context.restore();
}


    var canvas=document.getElementById("myCropCircle0511");
    var context=canvas.getContext("2d");

    var draw1=setTimeout("drawTriCircles(context,150,150,150,d)",1000);
    var draw2=setTimeout("drawAnotherLayerTriCircles(context,150,150,150,d)",2000);


    var CCDiv = document.getElementById('CCDiv');
    var d = 0;
    setInterval(function () {
      d = (d + 0.1) ;
      CCDiv.style.transform = 'rotate(' + d + 0 + 'deg)';
      CCDiv.style.OTransform = 'rotate(' + d + 0 + 'deg)';
      CCDiv.style.MozTransform = 'rotate(' + d + 0 + 'deg)';
      CCDiv.style.WebkitTransform = 'rotate(' + d + 0 + 'deg)';
}, 30);
-->
</script>

2011年5月7日 星期六

動新聞QR碼,擴增現實(Augmented Reality)與麥田圈(CropCircle)

Jimmy's papa相信許多人都聽過或玩過,動新聞QR碼或是擴增現實(Augmented Reality),這些技術大致上是透過攝影鏡頭去讀取類似二維條碼的code,經過電腦解讀後,藉由CPU超強的運算能力加上功能強大的程式庫去呈現多采多姿的3D多媒體效果,讓人類感官體驗另一次元的情境,雖然 Jimmy's papa知道技術上如何實作,可是每當眼光切換在單調無意義的黑白條碼及螢幕畫面的色彩絢麗的3d立體動畫,虛虛實實之間,讓人分不清楚真實及虛假的界線在哪裡

愛看科幻電影的Jimmy's papa覺得某些不可解的麥田圈(CropCircle)或許就是類似擴增現實(Augmented Reality)的code吧!而觀看的人就像智慧型手機,如果大腦有配備符合的解讀程式就能體驗到某些特別的經驗,所以去搜尋網路上一堆麥田圈的解讀網站,就可以看到許多有趣的說法,就像動新聞一樣越多人透過手機讀取QR碼,黎老闆就知道他的市場大餅有多大,哈哈!!

我科幻看太多了!!!

2011年5月5日 星期四

升級Ubuntu 11.04後Bluetooth無法開啟

最近Ubuntu 11.04已正式釋出,衝著為了迎接平板潮流的Unity介面,Jimmy's papa毫不猶豫的按下升級按鈕,經過漫長的下載升級過程,終於可以把玩新的使用者介面,但接下來執行BricxCC及JNXT時可把我嚇出一身冷汗,因為藍牙竟無法啟動,那意味著除非Ubuntu很快的針對這個bug出更新程式,否則會有一段時間無法教Jimmy寫機器人程式,頓時對著我的衝動的手指頭不禁懊惱起來,所幸經過這兩天的搜尋找到暫時解決的方法,就是到命令列視窗執行以下指令
sudo killall bluetoothd
sudo bluetoothd 
不過每次重新開機後,還是得再執行一次

用腦波打手機

以下這則新聞Jimmy's papa上個月看到時,就覺得這技術未來應該有潛力而且實作不難,可以把不同的閃爍頻率埋在應用程式的功能按鈕上,但是困難點在於這腦波訊號據研究者說只能在腦部的中線枕骨檢測到,消費性的BCI硬體目前大概只有Emotiv EPOC或許能偵測到那個點,如果前額腦也能檢測到的話,就能使用更便宜的BCI腦機介面實作這種技術了,或許不久的將來BCI會成為電腦的標準操作配備之一

華裔學者傑作 受益範圍廣 腦電波打電話試驗成功
   移民自台灣的聖地牙哥加大(UC San Diego)華裔研究員鍾子平,在研究腦電波控制物件有新突破,他的一個新研發的腦電波控制介面可讓用戶想着數字便可撥打電話,這研究或可幫助嚴重傷殘人士甚至一般民衆。研究員開發出新方法,讓用戶以思想來控制手機撥號。大多數人士只需簡短的訓練,便可操作這個新研發的人腦電腦介面,準確度近100%。

  負責這項研究是聖地牙哥加大Swartz運算神經科學中心研究員鍾子平及其同僚。據鍾子平表示,這極之便攜的系統除可協助嚴重傷殘人士外,他日可能有更廣泛用途。例如這可為手機用戶提供終極的免提通話體驗,或可用作量度駕駛人或航空管理員的集中力來檢測他們是否昏昏欲睡。

  一如其他的人腦操控介面,這系統依賴貼在頭皮上的腦電圖(electroencephalogram, EEG)電極來分析腦電波活動。研究員把一個EEG頭帶連接至一個藍芽組件,把訊號傳送至一部諾基亞(Nokia)的N73手機上,訊號再經由手機內的程式作處理。

  參與實驗人士利用一個嶄新的視覺回饋工具來進行訓練。研究員把圖像以不同閃爍頻率放上電腦顯示屏,這些肉眼几乎不察覺的閃爍可被腦部的中線枕骨檢測到。鍾子平與同僚把數字鍵顯示在屏幕上,每個數字有不同的閃爍頻率,例如1字的頻率為9Hz、2字為9.25Hz,依此類推。據鍾子平表示,EEG可檢測到這些頻率,故可知道用戶是在盯着那個數字

  鍾子平聲稱實驗顯示任何人也可應用這系統,一些人能做出較高的準確度,但他本人只能達到約85%的準確度。在一項已刊登在《神經工程學期刊》(Journal of Neural Engineering)的實驗中,10名接受測試人士按指示輸入10位數字的電話號碼,其中7人做出100%的準確度。

  鍾子平表示理論上這研究可助那些嚴重傷殘人士與別人溝通,但他相信這技術的應用不局限於此,並聲稱目標是更廣大的對象。

  曾在去年發表一項名為神經電話(Neurophone)類似概念的達特茅斯學院(Dartmouth College)認知神經科學家Ranjeev Raizada表示這是令人關注的研究,他指出過往曾有人使用這類視覺誘發回應技術,但把系統弄得更細小及更便宜並可應用在手機上這概念極之吸引。

2011年5月3日 星期二

在Ubuntu執行BricxCC的相關設定

由於從小Jimmy就是在Ubuntu作業系統的環境下一路走來,所以Jimmy's papa教Jimmy寫NXC程式,當然也是借助Ubuntu上的Wine執行BricxCC開發環境,不過還是得將某些配置選項勾選正確,才能成功地將.rxe編譯出來
寄件者 scratchlab

寄件者 scratchlab

不過Ubuntu 10.4上的Wine執行BricxCC開發環境,是無法將編譯好的.rxe檔push到NXT,這時就得靠JNXT了,雖然有點麻煩,但是幾次的教學下來,Jimmy不需我提醒也能按照每個步驟操作
寄件者 scratchlab

html5 Canvas測試大雜燴--多重Layers & Pre3d

This text is displayed if your browser does not support HTML5 Canvas. This text is displayed if your browser does not support HTML5 Canvas.

這是Jimmy's papa參考許多網站的範例程式後,覺得有些蠻有參考價值的,乾脆作個測試大雜燴,裡頭有黃澄澄的金色立方體是參考Pre3d的範例,而很炫的旋轉曲線漩渦效果是參考HTML5 Canvas Machines Vortex,分別繪製在3個重疊的canvas畫布上
以下是javascript程式碼
<section>

<div id="canvasesdiv" style="position:relative; width:500px; height:500px">
<canvas id="my3DCubeCanvas" style="z-index: 0;" width="500" height="500"></canvas>

<canvas id="layer1" style="z-index: 1;position:absolute;left:0px;top:0px;" height="500px" width="500">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
<canvas id="layer2" style="z-index: 2;position:absolute;left:0px;top:0px;" height="500px" width="500">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
</div>
    


<script src="pre3d.js"></script>
<script src="pre3d_shape_utils.js"></script>
<script src="demo_utils.js"></script>
<script>

function start3d() {
  var screen_canvas = document.getElementById("my3DCubeCanvas");

  var renderer = new Pre3d.Renderer(screen_canvas);

  var cube = Pre3d.ShapeUtils.makeCube(1);

  Pre3d.ShapeUtils.triangulate(cube);

  renderer.fill_rgba = new Pre3d.RGBA(1, 1, 0, 1);
  
  var state = {
    cube_rotate_y_rad: 0,
    cube_rotate_x_rad: 0,
    cube_x: 2,
    cube_y: 0
  };

  function draw() {
    renderer.transform.reset();
    renderer.transform.rotateX(state.cube_rotate_x_rad);
    renderer.transform.rotateY(state.cube_rotate_y_rad);
    renderer.transform.translate(state.cube_x, state.cube_y, 0);
    renderer.bufferShape(cube);

    // White background.
    renderer.ctx.setFillColor(1, 1, 1, 1);
    renderer.drawBackground();

    renderer.drawBuffer();
    renderer.emptyBuffer();
  }

  renderer.camera.focal_length = 2.5;
  DemoUtils.autoCamera(renderer, 0, 0, -8, 0, 0, 0, draw);

function spin_and_draw() {
    state.cube_rotate_y_rad += 0.1;
    state.cube_rotate_x_rad += 0.01;
    state.cube_x = Math.sin(state.cube_rotate_y_rad / 2) * 3;
    state.cube_y = Math.sin(state.cube_rotate_x_rad * 4) * 3;
    draw();
  };

  var ticker = new DemoUtils.Ticker(30, spin_and_draw);



  ticker.start();

  //draw();

}


start3d();
</script>

<script type="text/javascript">
var layer1;
var layer2;

var ctx1;
var ctx2;


var WIDTH = 500;
var HEIGHT = 500;
var nightcity = new Image();

var arcs=null;




function Arc(radius, startingAngle, endingAngle, width, color) {
    this.radius = radius;
    this.startingAngle=startingAngle;
    this.endingAngle=endingAngle;
    this.width=width;
    this.color=color;
    
    var speed=(Math.random() / 10) + 0.007; 

    this.speed = speed;
}

function setArcs() {
    var colors=new Array();

    colors.push("#5ef");
    colors.push("#6de");
    colors.push("#7cd");
    colors.push("#8bc");
    colors.push("#9ab");
    colors.push("#a9a");
    colors.push("#b89");
    colors.push("#c78");
    colors.push("#d67");
    colors.push("#e56");

    arcs=new Array();

    for (n=0; n<10; n++){
        var radius = (n+1) * 20;
        var width = (n+1) *6;

        var color=colors[n];

        
        var startingAngle = Math.floor(Math.random() * 2);
        var endingAngle = startingAngle + 1;
        
        arcs.push(new Arc(radius,startingAngle,
            endingAngle,width,color)); 
    }
    
}

function init() {
nightcity.src ="nightcity.png";
layer1 = document.getElementById("layer1");
ctx1 = layer1.getContext("2d");
setArcs();
layer2 = document.getElementById("layer2");
ctx2 = layer2.getContext("2d");

setInterval(drawAll, 20);
}

function drawAll() {
draw1();
draw2();

}

function draw1() {
    
    var layer1=document.getElementById("layer1");
    ctx1 = layer1.getContext("2d");
    ctx1.clearRect(0, 0, WIDTH, HEIGHT);

    for (n=0; n<10; n++) {
        var thisArc=arcs[n];
        var increment=thisArc.speed;
        
        thisArc.startingAngle-=increment;
        thisArc.endingAngle-=increment;    
    }
    
    
    var centerX = 250;
    var centerY = 250;
    
    
    for (n=0; n<10; n++) {
        ctx1.beginPath();
        var thisArc = arcs[n];
        ctx1.arc(centerX,centerY,thisArc.radius,thisArc.startingAngle* 
            Math.PI, thisArc.endingAngle* Math.PI,true);

        ctx1.lineWidth=thisArc.width; 
        
        ctx1.strokeStyle=thisArc.color; 
        ctx1.stroke();
        ctx1.closePath();
    }
    
}


function draw2() {
ctx2.clearRect(0, 0, WIDTH, HEIGHT);
ctx2.drawImage(nightcity, 0, 0);
}



init();
</script>

</section>