Parse
File Parse intersections.js
This tree is parsed live from the source file.
Classes
-
{{ item.name }}
- {{ key }}
Not Classes
{{ getTree() }}
Comments
{{ getTreeComments() }}
Source
let denomText = 'nothing'
const checkLinesIntersection = function(line, otherLine, length) {
const x1 = line[0].x;
const y1 = line[0].y;
// Normalize the direction vector (end - start) and apply the length
const dx = line[1].x - x1;
const dy = line[1].y - y1;
const magnitude = Math.sqrt(dx * dy + dy * dy);
let directionX = dx
let directionY = dy
if(length!== undefined) {
directionX = (dx / magnitude) * length;
directionY = (dy / magnitude) * length;
}
const x2 = line[0].x + directionX;
const y2 = line[0].y + directionY;
const x3 = otherLine[0].x;
const y3 = otherLine[0].y;
const x4 = otherLine[1].x;
const y4 = otherLine[1].y;
/* with two parallel lines, the denominator is zero */
const denominator = getDenominator(x1, y1, x2, y2, x3, y3, x4, y4)
denomText = denominator
if (denominator === 0) return false; // Parallel lines
const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denominator;
const u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / denominator;
if (t > 0 && t < 1 && u > 0 && u < 1) {
const intersectX = x1 + t * (x2 - x1);
const intersectY = y1 + t * (y2 - y1);
// Calculate the angle from the intersection point to the start of otherLine
// const angleRad = Math.atan2(y3 - intersectY, x3 - intersectX);
return {
x: intersectX
, y: intersectY
// , radians: angleRad
};
// return { x: intersectX, y: intersectY };
}
return false;
}
const getDotProduct = function(px, py, x1, y1, x2, y2){
return (px - x1) * (x2 - x1) + (py - y1) * (y2 - y1);
}
const getDenominator = function(x1, y1, x2, y2, x3, y3, x4, y4) {
return (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
}
const checkPointIntersectionOccured = function(line, point, radius=5, length=400) {
const x1 = line[0].x;
const y1 = line[0].y;
// Normalize the direction vector (end - start) and apply the length
const dx = line.last().x - x1;
const dy = line.last().y - y1;
const magnitude = Math.sqrt(dx * dx + dy * dy);
let directionX = (dx / magnitude) * length;
let directionY = (dy / magnitude) * length;
const x2 = line[0].x + directionX;
const y2 = line[0].y + directionY;
// The coordinates of the point to check
const px = point.x;
const py = point.y;
// Calculate the distance from the point to the line
const distance = Math.abs((x2 - x1) * (y1 - py) - (x1 - px) * (y2 - y1)) / Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
// Check if the point is within the radius
if (distance <= radius) {
// Check if the point is within the bounds of the segment
const dotProduct = (px - x1) * (x2 - x1) + (py - y1) * (y2 - y1);
if (dotProduct >= 0 && dotProduct <= (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) {
return true;
}
}
return false;
}
const checkPointIntersectionWithin = function(line, point, radius=5, length=400) {
const x1 = line[0].x;
const y1 = line[0].y;
// Normalize the direction vector (end - start) and apply the length
const dx = line.last().x - x1;
const dy = line.last().y - y1;
const magnitude = Math.sqrt(dx * dx + dy * dy);
let directionX = (dx / magnitude) * length;
let directionY = (dy / magnitude) * length;
const x2 = line[0].x + directionX;
const y2 = line[0].y + directionY;
// The coordinates of the point to check
const px = point.x;
const py = point.y;
// Calculate the distance from the point to the line
const distance = Math.abs((x2 - x1) * (y1 - py) - (x1 - px) * (y2 - y1)) / Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
// Check if the point is within the radius
if (distance <= radius) {
// Calculate the projection of the point onto the line (closest point on the line)
const t = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
// Ensure the projection is within the line segment
if (t >= 0 && t <= 1) {
const intersectX = x1 + t * (x2 - x1);
const intersectY = y1 + t * (y2 - y1);
return { x: intersectX, y: intersectY };
}
}
return false;
}
const checkPointIntersectionEdge = function(line, point, radius=point.radius, length=undefined) {
const x1 = line[0].x;
const y1 = line[0].y;
// Normalize the direction vector (end - start) and apply the length
const dx = line.last().x - x1;
const dy = line.last().y - y1;
const magnitude = Math.sqrt(dx * dx + dy * dy);
let directionX = dx
let directionY = dy
if(length!== undefined) {
directionX = (dx / magnitude) * length;
directionY = (dy / magnitude) * length;
}
const x2 = line[0].x + directionX;
const y2 = line[0].y + directionY;
// The coordinates of the point (center of the circle)
const cx = point.x;
const cy = point.y;
// Define the line as a vector from (x1, y1) to (x2, y2)
const dxLine = x2 - x1;
const dyLine = y2 - y1;
// A, B, and C coefficients for the quadratic equation Ax^2 + Bx + C = 0
const A = dxLine * dxLine + dyLine * dyLine;
const B = 2 * (dxLine * (x1 - cx) + dyLine * (y1 - cy));
const C = (x1 - cx) * (x1 - cx) + (y1 - cy) * (y1 - cy) - radius * radius;
// Calculate the discriminant
const discriminant = B * B - 4 * A * C;
// If the discriminant is negative, the line does not intersect the circle
if (discriminant < 0) {
return false;
}
// Calculate the two points of intersection
const t1 = (-B + Math.sqrt(discriminant)) / (2 * A);
const t2 = (-B - Math.sqrt(discriminant)) / (2 * A);
// Points of intersection
const intersectX1 = x1 + t1 * dxLine;
const intersectY1 = y1 + t1 * dyLine;
const intersectX2 = x1 + t2 * dxLine;
const intersectY2 = y1 + t2 * dyLine;
// Ensure the intersection points are within the line segment
if ((t1 >= 0 && t1 <= 1) || (t2 >= 0 && t2 <= 1)) {
const intersectionPoints = [];
if (t1 >= 0 && t1 <= 1) {
intersectionPoints.push({ x: intersectX1, y: intersectY1 });
}
if (t2 >= 0 && t2 <= 1) {
intersectionPoints.push({ x: intersectX2, y: intersectY2 });
}
return intersectionPoints;
}
return false;
}
function getCircleCircleIntersections(circle1, circle2) {
const { x: x0, y: y0, radius: r0 } = circle1;
const { x: x1, y: y1, radius: r1 } = circle2;
// Calculate distance between centers
const dx = x1 - x0;
const dy = y1 - y0;
const d = Math.hypot(dx, dy);
// Check for solvability
if (d > r0 + r1 || d < Math.abs(r0 - r1)) {
// No solution. Circles do not intersect.
return false;
}
// Check for coincident circles
if (d === 0 && r0 === r1) {
// Circles are coincident and there are infinite intersection points.
// For practical purposes, we can return false or handle accordingly.
return false;
}
// Calculate the point where the line through the circle intersection points crosses the line between the circle centers.
const a = (r0 * r0 - r1 * r1 + d * d) / (2 * d);
const h = Math.sqrt(r0 * r0 - a * a);
// Calculate midpoint between the two centers
const xm = x0 + (dx * a) / d;
const ym = y0 + (dy * a) / d;
// Calculate intersection points
const rx = -dy * (h / d);
const ry = dx * (h / d);
const intersection1 = { x: xm + rx, y: ym + ry };
const intersection2 = { x: xm - rx, y: ym - ry };
// If h == 0 then there is only one intersection point (circles touch externally or internally)
if (h === 0) {
return [intersection1];
}
return [intersection1, intersection2];
}
class PointIntersections {
constructor(point) {
this.parent = point
/* string stuff */
this.gravity = {x:0, y:1}
this.damping =.95
this.dotDamping =.2
this.forceMultiplier =.1
this.forceValue =undefined
this.distance = 100
}
of(other, settings) {
let p = getCircleCircleIntersections(this.parent, other, settings)
return PointList.from(p).cast()
}
}
Polypoint.head.deferredProp('Point',
function intersections() {
return new PointIntersections(this)
}
);
copy