Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <script src="sketch.js"></script>
    <div id="ui_container"></div>
  </body>
</html>

              
            
!

CSS

              
                html, body {
    margin: 0;
    padding: 0;
  }
  canvas {
    display: block;
    border: solid 1px;
  }
  
              
            
!

JS

              
                // ベクトルクラス
class Vec3 {
  constructor(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
}

// 位置クラス
class Point {
  constructor(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
}

// 線分クラス
class Line3D {
  constructor (_start_p, _end_p) {
    this.start_p = _start_p;
    this.end_p = _end_p;
    // ベクトルを設定
    this.v = new Vec3 (
      this.end_p.x - this.start_p.x,
      this.end_p.y - this.start_p.y,
      this.end_p.z - this.start_p.z
    );
  }
}

// 球クラス
class Ball3D {
  constructor (_p, _r) {
    this.p = _p;
    this.r = _r;
  }
}

// *** 座標ベクトル計算 ***
// ベクトル描画処理
function drawVecLine(vec, start_p) {
  end_p_x = start_p.x + vec.x;
  end_p_y = start_p.y + vec.y;
  end_p_z = start_p.z + vec.z;
  return line(start_p.x, start_p.y, start_p.z, end_p_x, end_p_y, end_p_z);
}

/**
 * 球と線分の衝突判定
 * 球の方程式と直線の方程式から求める
 * @param {Point}  ball_p 球の位置
 * @param {number} ball_r 球の半径
 * @param {Point}  line_p 線分の開始位置
 * @param {Vec3}   line_v 線分のベクトル
 * @returns true:衝突している false:衝突していない
 */
 function checkBallColLine(ball_p, ball_r, line_p, line_v) {
  // 直線の方程式と球の方程式より、
  // ax^2 + bx + c の形に変形し、a, b, cそれぞれの要素を求める
  let r = ball_r;
  let xa = line_p.x - ball_p.x;
  let ya = line_p.y - ball_p.y;
  let za = line_p.z - ball_p.z;
  let a = line_v.x*line_v.x + line_v.y*line_v.y + line_v.z*line_v.z;
  let b = 2.0 * (line_v.x*xa + line_v.y*ya + line_v.z*za);
  let c = xa*xa + ya*ya + za*za - r*r;
  // 解の公式よりtの値を求める
  // 「b^2-4ac」の値が0以下の場合、衝突無し
  let d = b*b - 4.0*a*c;
  if (d < 0) {
    return false;
  }
  // tの値(2つ)を求める
  d = Math.sqrt(d);
  let t1 = (-b + d) / (2.0 * a);
  let t2 = (-b - d) / (2.0 * a);
  // 線分の最寄り(最小値)のtを設定
  let t = 2.0;
  if (t1 >= 0.0 && t1 <= 1.0 && t1 < t) {
    t = t1;
  }
  if (t2 >= 0.0 && t2 <= 1.0 && t2 < t) {
    t = t2;
  }
  // tが1より大きい場合、衝突無し
  if (t > 1.0) {
    return false;
  }
  return true;
}

// *** 変数定義 ***
// 線分の座標
let line_start_p = new Point(100, 0, -100);
let line_end_p = new Point(-100, 0, 100);
let line3D = new Line3D(line_start_p, line_end_p);
// 球の座標
let ball_px = -100;
let ball_py = 0;
let ball_pz = 100;
let ball_p = new Point(ball_px, ball_py, ball_pz);
let ball_r = 30;
let ball3D = new Ball3D(ball_p, ball_r);
// 衝突判定結果
let bool_collision = checkBallColLine(ball3D.p, ball3D.r, line3D.start_p, line3D.v);

// *** 3D表示用SKETCH ***
// 初期設定処理
function setup() {
  // CANVAS設定(WEBGLを使用)
  createCanvas(400, 400, WEBGL);
  // ノーマルマテリアルを適用
  normalMaterial();
}

// 描画処理
function draw() {
  // マウスコントロールを設定
  orbitControl();
  // 背景色設定
  background(200);
  // 回転処理
  rotateX(radians(75));
  rotateZ(radians(45));
  // 平面描画
  push();
  beginShape();
  plane(250, 250);
  endShape();
  // 線分の描画
  strokeWeight(3);
  stroke(255, 0, 0);
  drawVecLine(line3D.v, line3D.start_p);
  pop();
  // 球の描画
  push();
  ball3D.p = new Point(ball_px, ball_py, ball_pz);
  translate(ball3D.p.x, ball3D.p.y, ball3D.p.z);
  sphere(ball3D.r);
  // 球と線分の衝突判定
  bool_collision = checkBallColLine(ball3D.p, ball3D.r, line3D.start_p, line3D.v);
  pop();
}

// *** UI表示用SKETCH ***
// WEBGL上で画面表示できないため別で作成
var ui_sketch = function(p) {

  // 初期設定処理
  p.setup = function() {
    p.createCanvas(400, 150);
    // ball_pスライダー
    ball_px_slider = createSlider(-200.0, 200.0, ball_px);
    ball_px_slider.position(230, 30);
    ball_px_slider.mouseReleased(setBallPx);
    ball_py_slider = createSlider(-200.0, 200.0, ball_py);
    ball_py_slider.position(230, 50);
    ball_py_slider.mouseReleased(setBallPy);
    ball_pz_slider = createSlider(-200.0, 200.0, ball_pz);
    ball_pz_slider.position(230, 70);
    ball_pz_slider.mouseReleased(setBallPz);
  };

  // 描画処理
  p.draw = function() {
    // 背景設定
    p.background(150);
    // テキスト描画
    p.fill(0);
    p.noStroke();
    p.textSize(15);
    p.fill(0, 0, 0);
    p.text("[球の位置] " + "(" + ball_px + ", " + ball_py + ", " + ball_pz + ")", 230, 30);
    p.text("[衝突判定] " + (bool_collision ? "衝突!!" : "衝突無し"), 230, 110);
    p.fill(0, 0, 255);
  };

  // *** スライダー値設定 ***
  function setBallPx() {
    ball_px = ball_px_slider.value();
  }
  function setBallPy() {
    ball_py = ball_py_slider.value();
  }
  function setBallPz() {
    ball_pz = ball_pz_slider.value();
  }
};
new p5(ui_sketch, "ui_container");

              
            
!
999px

Console