@stelmashchuk/autocad-dxf
Version:
A module which can be used to parse AutoCAD dxf files and to make programmatic and geometric operations on the AutoCAD drawing entities.
160 lines (137 loc) • 4.09 kB
JavaScript
const Intersection = require("./Intersection");
const ErrorMessages = require("./ErrorMessages.json");
const istangent = (line, circle, plane, getAxes, tolerance) => {
if (typeof circle != "object" || typeof line != "object") {
throw new Error(ErrorMessages.INCORRECT_PARAMS);
return;
}
let [ax1, ax2] = getAxes(plane);
if (plane && ax1 === undefined && ax2 === undefined) {
throw new Error(ErrorMessages.INCORRECT_PARAMS);
return;
}
const x0 = line[`start_${ax1}`];
const y0 = line[`start_${ax2}`];
const x1 = line[`end_${ax1}`];
const y1 = line[`end_${ax2}`];
const slope = (y1 - y0)/(x1 - x0);
if (Math.abs(slope) == Infinity) {
return Math.abs(Math.abs(circle[ax1] - x0) - circle.radius) < tolerance;
} else {
const len = Math.abs(-slope*circle[ax1] + circle[ax2] + slope*x0 - y0)/(Math.sqrt(1 + slope*slope));
return Math.abs(len - circle.radius) < tolerance;
}
return false;
};
const tangent = (circle, angle, length, plane, getAxes, tolerance) => {
if (typeof circle != "object") {
throw new Error(ErrorMessages.INCORRECT_PARAMS);
return;
}
let [ax1, ax2] = getAxes(plane);
if (plane && ax1 === undefined && ax2 === undefined) {
throw new Error(ErrorMessages.INCORRECT_PARAMS);
return;
}
if (Array.isArray(angle)) {
const x = angle[0];
const y = angle[1];
const r = circle.radius;
const xc = circle[ax1];
const yc = circle[ax2];
const len = (x - xc)*(x - xc) + (y - yc)*(y - yc) - r*r;
if (len < 0) { // point inside the circle
return [];
}
const m = -(xc - x)/(yc - y);
let b;
if (Math.abs(m) == Infinity) {
const theta = Math.asin(r/Math.sqrt(len));
m = Math.tan(Math.PI/2 - theta);
b = -m*x + y;
} else {
b = -(r*r - len + x*x - xc*xc + y*y - yc*yc)/(2*(yc - y));
}
const A = m*m + 1;
const B = 2*(m*(b - yc) - xc);
const C = xc*xc + (b - yc)*(b - yc) - r*r;
const det = B*B - 4*A*C;
let xint1, yint1, xint2, yint2;
if (det == 0) {
xint1 = (-B)/(2*A);
yint1 = m*sol1 + b;
} else if (det > 0) {
xint1 = (-B + Math.sqrt(det))/(2*A);
xint2 = (-B - Math.sqrt(det))/(2*A);
yint1 = m*xint1 + b;
yint2 = m*xint2 + b;
}
let points = [];
if (!isNaN(xint1) && !isNaN(yint1)) {
let json = {};
json[ax1] = xint1;
json[ax2] = yint1;
json.angle = Math.atan2((yint1 - circle[ax2]), (xint1 - circle[ax1]));
points.push(json);
}
if (!isNaN(xint2) && !isNaN(yint2)) {
let json = {};
json[ax1] = xint2;
json[ax2] = yint2;
json.angle = Math.atan2((yint2 - circle[ax2]), (xint2 - circle[ax1]));
points.push(json);
}
return points;
} else {
return tangent2(circle, angle, length, plane, getAxes, tolerance);
}
return;
};
const tangent2 = (circle, angle, length, plane, getAxes, tolerance) => {
if (typeof circle != "object") {
throw new Error(ErrorMessages.INCORRECT_PARAMS);
return;
}
let [ax1, ax2] = getAxes(plane);
if (plane && ax1 === undefined && ax2 === undefined) {
throw new Error(ErrorMessages.INCORRECT_PARAMS);
return;
}
const r = circle.radius;
const x = circle[ax1] + r*Math.cos(angle);
const y = circle[ax2] + r*Math.sin(angle);
const xc = circle[ax1];
const yc = circle[ax2];
const slope = (y - yc)/(x - xc);
const m = -1/slope;
let json1 = {}, json2 = {};
json1[`start_${ax1}`] = x;
json1[`start_${ax2}`] = y;
json2[`start_${ax1}`] = x;
json2[`start_${ax2}`] = y;
if (Math.abs(m) == Infinity) {
json1[`end_${ax1}`] = x;
json1[`end_${ax2}`] = y + length;
json2[`end_${ax1}`] = x;
json2[`end_${ax2}`] = y - length;
} else {
const b = y - m*x;
const A = m*m + 1;
const B = 2*(m*(b - y) - x);
const C = x*x + (b - y)*(b - y) - length*length;
const det = B*B - 4*A*C;
const sol1 = (-B + Math.sqrt(det))/(2*A);
const sol2 = (-B - Math.sqrt(det))/(2*A);
const ysol1 = m*sol1 + b;
const ysol2 = m*sol2 + b;
json1[`end_${ax1}`] = sol1;
json1[`end_${ax2}`] = ysol1;
json2[`end_${ax1}`] = sol2;
json2[`end_${ax2}`] = ysol2;
}
return [json1, json2];
};
module.exports = {
istangent: istangent,
tangent: tangent
};