質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.60%

  • JavaScript

    15932questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • canvas

    251questions

    HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

何故、切り捨てると0除算してしまうのか。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 185

aaaaaaaa

score 465

下記のソースのプロパティであるthis.startLifeの小数点の丸め方(端数処理)を切り上げ(ceil)ではなく切り捨て(floor)にすると実行途中にエラーが発生してしまいます。
エラー直前に0除算をしているようです。切り上げにするとこのようなことは、発生しません。

var canvas = document.getElementById("canvas"),

ctx = canvas.getContext("2d"),

//パーティクルの数
NUM = 22,//22
LIFEMAX = 100,//寿命の上限
particles = [],
//図形の描画範囲
W = 500,
H = 500;

canvas.width =  canvas.height=500;//500pxと同義。


window.requestAnimationFrame =
  window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(cb) {setTimeout(cb,17);};


function Particle(ctx,x,y) {
  this.ctx = ctx;
    this.initialize(x,y);
}
Particle.prototype.initialize = function(x,y) {
  this.x= x||0;
    this.y= y||0;
    this.radius=250;//終了円の半径
  this.startLife = Math.floor(LIFEMAX*Math.random());//寿命の始まり(寿命の初期値)※ここをfloorにするとなぜかエラーとなる
  this.life= this.startLife;//現在の寿命
  console.log("startLife",this.startLife,"life",this.life)

    //速度用のオブジェクトv
    this.v= {
        x:Math.random()*10-5,//X方向の速度。-5から4.9999...の何れかの数値がプロパティに代入される。
        y:Math.random()*10-5//y方向の速度。
    };
  this.color = {//floorは、少数を切り捨てる関数でrandomが0~0.9999...までの何れかの数値を算出する関数。
    r:Math.floor(Math.random()*255),
    g:Math.floor(Math.random()*255),
    b:Math.floor(Math.random()*255),
    a:1
  };
};

for(var i=0; i<NUM;i++) {
    positionX = Math.random() * 20;//X座標を0-19.9999...の間でランダムに
    positionY = Math.random() * 20;//Y座標を0-19.9999...の間でランダムに
      //初期配置と2dコンテキストをParticleに渡す。
    particle = new Particle(ctx,positionX,positionY);
    particles.push(particle);
}


//図形をずらす
Particle.prototype.render = function() {
    //console.log("あ",typeof draw);
    this.updateParams();
    this.updatePosition();
        this.wrapPosition();//canvas外に消えた図形を要素内に再び表示させる。
      this.draw();
};

//図形を描画する処理
Particle.prototype.draw = function() {
    //.4再度図形を描画する。
    ctx = this.ctx;

        //パスを初期化。ここでいうパスとは、領域の境界線のようなものだという。
    ctx.beginPath();

    ctx.fillStyle = this.gradient();//階調

    //ctx.rect(this.x,this.y,10,20);

    //円形のパスを作成。Math.PIは、円の直径と円周の比率(円周/直径)、つまり円周率3.14...を返すやつだ。
    ctx.arc(this.x,this.y,this.radius,2*Math.PI,false);

    ctx.fill();

    //図形が重なった部分は、溶け合うように描写され、色が混ざりあうので白に近くなる。
    ctx.globalCompositeOperation="lighter";

    ctx.closePath();
};

Particle.prototype.updateParams = function() {
  var ratio = this.life/this.startLife;//寿命がどれくらい残っているか計算
  console.log("計算式",this.life,"/",this.startLife)
  console.log("ratio",ratio);
  this.color.a=1-ratio;//ratioは1から0まで変化
  this.radius = 30/ratio;//寿命に応じて半径も変化させる。
  this.life-=1;//lifeを減らす
  if(this.life===0) this.initialize();//lifeが0になったら再初期化
}

//描画した図形の位置をずらす
Particle.prototype.updatePosition = function() {
    //3.位置をずらす
    this.x +=this.v.x;
    this.y +=this.v.y;
};

Particle.prototype.wrapPosition = function() {
    //描画する図形が左端を超えてcanvas外に消えていったらcanvasの右端に消えていった図形を
    //表示するようにする。逆に右端を超えて消えたら左端から描画した図形を表示させる。
  if(this.x<0) this.x=W;
    if(this.x>W) this.x=0;
    if(this.y<0) this.y=H;
    if(this.y>H) this.y=0;
};

Particle.prototype.gradient = function() {
  var col = this.color.r+","+this.color.g+","+this.color.b;
    var g = this.ctx.createRadialGradient(this.x,this.y,0,this.x,this.y,this.radius);
    g.addColorStop(0,"rgba("+col+","+(this.color.a*1)+")");
    g.addColorStop(0.5,"rgba("+col+","+(this.color.a*0.2)+")");
    g.addColorStop(1,"rgba("+col+","+(this.color.a*0)+")");
    return g;
};


//1.図形を描画する。(描画サイクルの開始)
render();

function render() {
    //2.一度図形を消去する
    ctx.clearRect(0,0,W,H);

    //配列の各要素の関数renderを実行して図形を描画
    particles.forEach(function(e) {e.render();});

    //5.一定時間を置く
    requestAnimationFrame(render);
}


jsdoit

実際のエラーが発生している画面
https://gyazo.com/06a86491ccd5ac7e288ed71993036939
![エラー画面](9c82e5c48745dd1132ea81f4f814e5cb.png)

なぜ、切り捨てるとゼロ除算してしまうのでしょうか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+3

切り捨ての結果1未満の数値が0になってそれで除算したからです。

「1未満になるはずがないのになぜ0割りになるか?」

というご質問だろうと思うのですが、Math.random()は0以上1未満の疑似的な一様乱数を浮動小数点数つまり疑似的な実数で返す関数です。それに100を乗じたら0以上100未満の浮動小数点数になります。1%ほどですが0になる確率はあるということです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    15932questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • canvas

    251questions

    HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。