Я пытаюсь разобраться, как рассчитать пересечение между линией и краями произвольного c многоугольника в P5 - https://editor.p5js.org/knectar/sketches/5c-M8K7bS
Проблема в том, что что пересечения не совпадают с линией.
Похоже, есть проблема с формулой наклона, есть идеи по устранению неполадок?
var clickState = 0;
var cellSize = 200;
var gridSize = 400;
var fault;
function setup() {
createCanvas(windowWidth, windowHeight);
// cellSize = floor(width/5);
let cols = floor(width / gridSize);
let rows = floor(height / gridSize);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
cellArr.push(new Cell(i * gridSize, j * gridSize));
}
}
for (let i = cellArr.length - 1; i >= 0; i--) {
cellArr[i].calcSlopes();
break;
}
fault = new Fault(random(width), 0, random(width), height);
}
function draw() {
background(10);
push();
// translate(width / 3, height / 3);
for (let i = cellArr.length - 1; i > 0; i--) {
// cellArr[i].calcSlopes();
cellArr[i].drawCell();
cellArr[i].cellNum(i - 1);
break;
}
pop();
if (clickState == 1) {
fault.end = createVector(mouseX, mouseY);
if (fault) {
fault.render();
for (let i = cellArr.length - 1; i >= 0; i--) {
cellArr[i].slice(fault);
}
}
}
// console.log(cellArr[0]);
// noLoop();
}
class Cell {
constructor(x, y) {
this.centerPos = createVector(x, y);
this.vertCount = floor(random(4, 10));
this.vertArr = [];
this.makeCell();
this.clr = color(random(150, 255), random(0, 40), random(150, 245), 125);
}
makeCell() {
for (let i = 0; i < this.vertCount; i++) {
let angle = map(i, 0, this.vertCount, 0, TWO_PI);
let r = cellSize + random(-cellSize, cellSize);
let x = this.centerPos.x + r * cos(angle);
let y = this.centerPos.y + r * sin(angle);
this.vertArr.push({
pos: createVector(x, y),
m: 0,
b: 0
})
}
}
calcSlopes() {
let curr, prev, b, slope;
curr = createVector(this.vertArr[0].pos.x, this.vertArr[0].pos.y);
this.vertArr.push({
pos: createVector(curr.x, curr.y),
m: 0,
b: 0
})
for (let i = this.vertArr.length - 1; i > 0; i--) {
curr = createVector(this.vertArr[i].pos.x, this.vertArr[i].pos.y);
prev = createVector(this.vertArr[i - 1].pos.x, this.vertArr[i - 1].pos.y);
slope = (curr.y - prev.y) / (curr.x - prev.x);
b = prev.y - (slope * prev.x);
this.vertArr[i] = ({
pos: createVector(curr.x, curr.y),
m: slope,
b: b
})
}
}
cellNum(num) {
text(num, this.centerPos.x, this.centerPos.y);
}
drawCell() {
// ellipse(100, 100, 100);
stroke(200);
strokeWeight(1);
fill(this.clr);
beginShape();
for (let i = 0; i < this.vertArr.length; i++) {
vertex(this.vertArr[i].pos.x, this.vertArr[i].pos.y);
}
endShape(CLOSE);
}
slice(fault) {
// y = (fault_m * x) + fault_b
// y = (regionLineM * x) + regionLineB
// (fault_m * x) - (regionLineM * x) = regionLineB - fault_b
// x = (regionLineB - fault_b) / (regionLineM + fault_m)
// y = (regionLineM * x) + regionLineB
let fault_m = fault.m;
let fault_b = fault.b;
// console.log("fault_m: " + fault_m);
for (let edge of this.vertArr) {
let cellLineM = edge.m;
let cellLineB = edge.b;
let intersectionX = (cellLineB - fault_b) / (cellLineM + fault_m);
let intersectionY = (cellLineM * intersectionX) + cellLineB;
noStroke();
fill(200, 140);
ellipse(intersectionX, intersectionY, 20);
}
}
}
class Fault {
constructor(sx, sy, ex, ey) {
this.start = createVector(sx, sy);
this.end = createVector(ex, ey);
this.b = 0;
this.m = 0;
}
render() {
this.calcFormula();
stroke(200);
strokeWeight(1);
let topIntercept;
let botIntercept;
topIntercept = -this.b / this.m;
// console.log("Orig_slope: " + this.m);
botIntercept = (height - this.b) / this.m;
this.end = createVector(botIntercept, height);
line(topIntercept, 0, botIntercept, height);
}
calcFormula() {
this.m = (this.end.y - this.start.y) / (this.end.x - this.start.x);
this.b = this.start.y - (this.m * this.start.x);
}
}
function mouseClicked() {
if (clickState == 0) {
fault.start = createVector(mouseX, mouseY);
}
clickState++;
if (clickState == 2) {
clickState = 0;
}
}```