@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.
73 lines (68 loc) • 2.95 kB
JavaScript
const Triangulate = require("./Triangulate");
const BSpline = require("./BSpline");
const ErrorMessages = require("./ErrorMessages.json");
module.exports = (entity, plane, getAxes, tolerance) => {
if (typeof entity != "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 etype = entity.subclass;
if (etype == "AcDbPolyline") {
let sum = 0;
let triangles = Triangulate(entity.vertices, plane, getAxes, tolerance);
for (let i = 0; i < triangles.length; i++) {
let triangle = triangles[i];
const L1 = Math.sqrt((triangle[0][ax1] - triangle[1][ax1])*(triangle[0][ax1] - triangle[1][ax1]) + (triangle[0][ax2] - triangle[1][ax2])*(triangle[0][ax2] - triangle[1][ax2]));
const L2 = Math.sqrt((triangle[0][ax1] - triangle[2][ax1])*(triangle[0][ax1] - triangle[2][ax1]) + (triangle[0][ax2] - triangle[2][ax2])*(triangle[0][ax2] - triangle[2][ax2]));
const L3 = Math.sqrt((triangle[2][ax1] - triangle[1][ax1])*(triangle[2][ax1] - triangle[1][ax1]) + (triangle[2][ax2] - triangle[1][ax2])*(triangle[2][ax2] - triangle[1][ax2]));
const S = (L1 + L2 + L3)/2;
const area = Math.sqrt(S*(S - L1)*(S-L2)*(S - L3));
sum = sum + area;
}
return {area: sum};
} else if (etype == "AcDbCircle" && entity.etype == "CIRCLE") {
const r = entity.radius;
return {area: Math.PI*r*r};
} else if (etype == "AcDbCircle" && entity.etype == "ARC") {
const r = entity.radius;
const start_angle = entity.start_angle;
const end_angle = entity.end_angle;
let d;
if (start_angle < end_angle) {
d = Math.abs(start_angle - end_angle);
} else {
d = 360 - Math.abs(start_angle - end_angle);
}
const A = Math.PI*r*r*d/360;
return {area: A - r*r*Math.cos(d*Math.PI/360)*Math.sin(d*Math.PI/360), area_sector: A};
} else if (etype == "AcDbEllipse") {
const start_angle = entity.start_angle2*Math.PI/180;
const end_angle = entity.end_angle2*Math.PI/180;
const dx = entity[`major_end_d${ax1}`];
const dy = entity[`major_end_d${ax2}`];
const ratio = entity.minorToMajor;
const a = Math.sqrt(dx*dx + dy*dy);
const b = ratio*a;
const a1 = Math.tan(end_angle) > 100000 ? Math.PI/2 : (Math.tan(end_angle) < -100000 ? 3*Math.PI/2 : Math.atan(a*Math.tan(end_angle)/b));
const a2 = Math.tan(start_angle) > 100000 ? Math.PI/2 : (Math.tan(start_angle) < -100000 ? 3*Math.PI/2 : Math.atan(a*Math.tan(start_angle)/b));
const A = 0.5*a*b*Math.abs(a1 - a2);
const A2 = 0.5*a*b*(Math.abs(a1 - a2) - Math.sin(Math.abs(a1 - a2)));
let json = {area: Math.PI*a*b - A2};
if (A > 0.000001) {
json.area_sector = A;
}
if (A2 > 0.000001) {
json.area_full = Math.PI*a*b;
}
return json;
} else if (etype == "AcDbSpline") {
const result = BSpline(entity);
return {area: result.area } //Approximate
}
return {};
};