erqerwqrqwere

🧩 Syntax:
class Vec2 {
  /**
   * @param {number} x
   * @param {number} y
   */
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  /**
   * @param {Vec2} b
   */
  add(b) {
    let a = this;
    return new Vec2(a.x+b.x, a.y+b.y);
  }
  /**
   * @param {Vec2} b
   */
  sub(b) {
    let a = this;
    return new Vec2(a.x-b.x, a.y-b.y);
  }
  copy() {
    return new Vec2(this.x, this.y);
  }
  /**
   * @param {number} s
   */
  mul(s) {
    return new Vec2(s*this.x, s*this.y);
  }
  mag() {
    return sqrt(this.x ** 2 + this.y ** 2);
  }
  rotate(rad) {
    return new Vec2(
      this.x*cos(rad) - this.y*sin(rad),
      this.x*sin(rad) + this.y*cos(rad)
    );
  }
}

class Ray2 {
  /**
   * @param {Vec2} pos ć“ć®ćƒ¬ć‚¤ć®å§‹ē‚¹ć®ä½ē½®ćƒ™ć‚Æćƒˆćƒ«.
   * @param {Vec2} way ć“ć®ćƒ¬ć‚¤ć®å§‹ē‚¹ć‹ć‚‰ä¼øć³ć‚‹ę–¹å‘ćƒ™ć‚Æćƒˆćƒ«.
   */
  constructor(pos, way) {
    this.pos = pos;
    this.way = way;
  }
  /**
   * @param {Vec2} begin
   * @param {Vec2} end
   */
  static withPoints(begin, end) {
    return new Ray2(begin, end.sub(begin));
  }
  get begin() {
    return this.pos;
  }
  get end() {
    return this.pos.add(this.way);
  }
}

let field = [
  [1,1,1,0,1],
  [1,0,0,0,1],
  [0,0,1,0,1],
  [0,1,1,1,1],
  [0,0,0,0,1],
];

let fieldGet = (x,y) => x>=0 && x<5 && y>=0 && y<5 ?
  field[y][x] : 0;

function setup() {
  createCanvas(640, 640);
}

function draw() {
  background(200); 

  //drawIntersection();
  
  //----- ć‚°ćƒŖćƒƒćƒ‰äøŠć«ć‚ć‚‹å£ćØē·šåˆ†ć®äŗ¤ē‚¹ć®ć‚„ć¤
  let s = 120;
  
  let p = mouseX/320 - 1;
  let q = mouseY;
  let y = (x) => p*x + q;
  let x = (y) => (y-q)/p;
  
  strokeWeight(2);
  for(let j=0; j<5; j++) {
    for(let k=0; k<5; k++) {
      if (field[k][j] === 0) {
        noFill();
      }else{
        fill(255);
      }
      rect(s*j, s*k, s, s);
    }
  }
  
  line(0, y(0), 640, y(640));
  
  //----- äŗ¤ē‚¹ć‚’ęē”»
  
  // äŗ¤ē‚¹ć®å€™č£œ (x=0,1,2... と y=0,1,2... の交点)
  let xKouho = [];
  let yKouho = [];
  for(let i=0; i<5; i++) {
    xKouho.push([i*s, y(i*s)]);
    yKouho.push([x(i*s), i*s]);
  }
  
  // å€™č£œć‹ć‚‰äŗ¤ē‚¹ć‚’čØˆē®—ć™ć‚‹ļ¼ˆå£ć«ć‚ćŸć£ć¦ć„ć‚‹ć‚‚ć®ć ć‘ć«ēµžć‚‹ļ¼‰
  let xKouten = xKouho.filter(
    k => fieldGet(int(k[0]/s), int(k[1]/s)) === 1 || fieldGet(int(k[0]/s - 1), int(k[1]/s)) === 1
  );
  let yKouten = yKouho.filter(
    k => fieldGet(int(k[0]/s), int(k[1]/s)) === 1 || fieldGet(int(k[0]/s), int(k[1]/s) - 1) === 1
  );
  
  // xyćƒćƒ©ćƒćƒ©ć«ćŖć£ć¦ć‚‹äŗ¤ē‚¹ć‚’ć¾ćØć‚ć‚‹
  let kouten = [...xKouten, ...yKouten];
  
  // ćƒžć‚¦ć‚¹ć‹ć‚‰čæ‘ć„ć»ć©é…åˆ—ć®å…ˆé ­ć«ćć‚‹ć‚ˆć†ć‚½ćƒ¼ćƒˆ
  let m = new Vec2(mouseX, mouseY);
  kouten.sort(
    (a,b) => {
      let p = new Vec2(...a).sub(m).mag();
      let q = new Vec2(...b).sub(m).mag();
      return p - q;
    }
  );
  // ćƒžć‚¦ć‚¹ć‹ć‚‰äø€ē•Ŗčæ‘ć„ļ¼ˆ0番目の交点)を選ぶ
  let firstKouten = kouten[0];
  
  strokeWeight(12);
  if (firstKouten !== undefined) {
    point(...firstKouten);
  }
}

function drawIntersection() {
  let L1 = new Ray2(new Vec2(100,200), new Vec2(200,50));
  let L2 = new Ray2(new Vec2(200,100), new Vec2(mouseX-200,mouseY-100));
  
  //----- äŗ¤ē‚¹ć‚’čØˆē®—
  let x1 = L1.pos.x;
  let y1 = L1.pos.y;
  let t1 = L1.way.y / L1.way.x;
  let left1 = min(L1.pos.add(L1.way).x, L1.pos.x);
  let right1 = max(L1.pos.add(L1.way).x, L1.pos.x);
  
  let x2 = L2.pos.x;
  let y2 = L2.pos.y;
  let t2 = L2.way.y / L2.way.x;
  let left2 = min(L2.pos.add(L2.way).x, L2.pos.x);
  let right2 = max(L2.pos.add(L2.way).x, L2.pos.x);
  
  let x = (t1*x1 - t2*x2 - y1 + y2) / (t1 - t2);
  let y = t1*(x - x1) + y1;
  //----- ここまで
  
  strokeWeight(4);
  line(L1.pos.x, L1.pos.y, L1.end.x, L1.end.y);
  line(L2.pos.x, L2.pos.y, L2.end.x, L2.end.y);
  
  strokeWeight(15);

  if (left1 < x && x < right1 && left2 < x && x < right2) {
    point(x, y);
  }
}