/* * iGeom by LInE * Geometric Object: Straight Line * www.matematica.br/igeom * ./app/components/line-component/models/line-model.js * Model to Straight Line */ import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum"; import { LineSegmentModel } from "../../line-segment-component/models/line-segment-model"; import { IntersectionModel } from "../../intersection-component/models/intersection-model"; const Erro = 0.00001; //TODO a definir... export class LineModel extends LineSegmentModel { constructor(pointA, pointB, label, id) { super(pointA, pointB, undefined, label, id); this.setClass(ELEMENTS_CLASS.LINE); } // Overload the Segment 'insideSegment' method (otherwise point intersection could be hiden) insideSegment(intersecX, intersecY) { //TODO Sempre verificar se esta dentro, nao parece bom... return true; } // Intersection with circunference getIntersectionWithCircumference(circ) { // circ = circunference(C,radius) // Delegate to super class Segment return super.getIntersectionWithCircumference(circ); } // Intersection between Straigh Lines (SL): with sl // r := this=SL(A1,A2) e s := SL(B1,B2) // \ / // o P=(x,y) // / \ // o \ o O2 (orthogonal to B2-B1) // O1 ort. to o / A2 oB1 // A2-A1 O1\ / \ // o oB2 // / A1 \ // this=r s // d1:=(A2.x-A1.x, A2.y-A1.y) => o1:=(-d1.y, d1.x) : ortogonais as retas r e s // d2:=(B2.x-B1.x, B2.y-B1.y) => o2:=(-d2.y, d2.x) : // Find P=(x,y) such that (inner product) // O1' P = O1' A1 (1) // O2' P = O2' B1 (2) // (1) => O1.x * x + O1.y * y = O1.x * A1.x + O1.y * A1.y => O2.y * (O1.x * x + O1.y * y) = O2.y * (O1.x * A1.x + O1.y * A1.y) (3) // (2) => O2.x * x + O2.y * y = O2.x * B1.x + O2.y * B1.y => O1.y * (O2.x * x + O2.y * y) = O1.y * (O2.x * B1.x + O2.y * B1.y) (4) // // (3)-(4) = O2.y * O1.x * x - O1.y * O2.x * x = O2.y * (O1.x * A1.x + O1.y * A1.y) - O1.y * (O2.x * B1.x + O2.y * B1.y) // = x * (O2.y * O1.x - O1.y * O2.x) = O2.y * (O1.x * A1.x + O1.y * A1.y) - O1.y * (O2.x * B1.x + O2.y * B1.y) // => x = ( O2.y * (O1.x * A1.x + O1.y * A1.y) - O1.y * (O2.x * B1.x + O2.y * B1.y) ) / (O2.y * O1.x - O1.y * O2.x) // // If O1.y<>0 => y = (O1.x * A1.x + O1.y * A1.y - O1.x * x) / O1.y // otherwise O2.y<>0 => y = (O2.x * B1.x + O2.y * B1.y - O2.x * x) / O2.y // // Return: .app/components/intersection-component/models/intersection-model.js getIntersectionWithStraightLine(sl) { try {//D //leo const A1 = this.pointA, A2 = this.pointB; // this = SL(A1,A2) const A3 = sl.pointA, A4 = sl.pointB; // sl = SL(A3, A4) var A1x = A1.posX, A1y = A1.posY, // A1 -> this A2x = A2.posX, A2y = A2.posY; // A2 -> this var B1x = A3.posX, B1y = A3.posY, // B1 -> sl B2x = A4.posX, B2y = A4.posY; // B2 -> sl var d1x = A2x - A1x, d1y = A2y - A1y, // d1 = A2-A1 d2x = B2x - B1x, d2y = B2y - B1y, // d2 = B2-B1 O1x = -d1y, O1y = d1x, // O1 = (-d1.y, d1.x) ortogonal a reta r=this O2x = -d2y, O2y = d2x, // O2 = (-d2.y, d2.x) ortogonal a reta s x, y; // P=(x,y) ponto procurado if (O2y * O1x - O1y * O2x == 0) { // "Reta: erro, divisao por zero" console.log("/app/components/line-component/models/line-model.js: erro: divisao por zero!"); return null; } x = (O2y * (O1x * A1x + O1y * A1y) - O1y * (O2x * B1x + O2y * B1y)) / (O2y * O1x - O1y * O2x); if (Math.abs(O1y) > Erro) y = (O1x * A1x + O1y * A1y - O1x * x) / O1y; else if (Math.abs(O2y) > Erro) y = (O2x * B1x + O2y * B1y - O2x * x) / O2y; else if (O1y != 0.0) y = (O1x * A1x + O1y * A1y - O1x * x) / O1y; else if (O2y != 0.0) y = (O2x * B1x + O2y * B1y - O2x * x) / O2y; else { console.log("/app/components/line-component/models/line-model.js: erro: O2y=0!"); return null; } //D console.log("line-model.js: getIntersectionWithStraightLine(sl): (" + x + "," + y + ") = " + //D "inter(r(P("+A1x+","+A1y+"),P("+A2x+","+A2y+")), s(P("+B1x+","+B1y+"),P("+B2x+","+B2y+"))"); return [new IntersectionModel(x, y, undefined, this, sl, true, 0)]; } catch (e) { console.log("app/components/line-component/models/line-model.js: getIntersectionWithStraightLine(.): erro!\n" + e.stack); } } // getIntersectionWithStraightLine(sl) // Intersection between Straigh Line (SL) and Segment (S) // P in S(C,D) <=> P = a C+(1-a)D, a em [0,1] then | Px = Ax+b(Bx-Ax) = a*Cx + (1-a)Dx and Py = Ay+b(By-Ay) = a*Cy + (1-a)Dy and // P in SL(A,B) <=> P = A + b(B-A) ---> | b = (a*Cx + (1-a)Dx - Ax)/(Bx-Ax) getIntersectionWithSegment(segm) { //const pointA = segm.pointA; //const pointB = segm.pointB; return segm.getIntersectionByLine(this); //TODO nome em './app/components/line-segment-component/models/line-segment-model.js ! getIntersectionByLine(.)' deveria ser 'getIntersectionWithSegment' } // Starting point to intersection started with StraightLine getIntersection(geometricObject) { try { //D //leo //D console.log("line-model.js.getIntersection: tipo=" + geometricObject.elementClass); switch (geometricObject.elementClass) { // ./app/core/enums/elements-class-enum.js: POINT=0; INTERSECTION_POINT=1; CIRCUMFERENCE=3; LINE=4; LINE_SEGMENT=6,... case ELEMENTS_CLASS.LINE: return this.getIntersectionWithStraightLine(geometricObject); //TODO melhor 'with' que 'by' case ELEMENTS_CLASS.LINE_SEGMENT: return this.getIntersectionWithStraightLine(geometricObject); //TODO melhor 'with' que 'by' case ELEMENTS_CLASS.CIRCUMFERENCE: return this.getIntersectionWithCircumference(geometricObject); //TODO melhor 'with' que 'by' default: break; } } catch (e) { console.log("app/components/line-component/models/line-model.js: getIntersection(.): erro!\n" + e.stack); } } static do(map, list) { const id = map.get("id"); const pointAId = map.get("param")[0]; const pointBId = map.get("param")[1]; const pointA = list.find(x => x.id === pointAId); const pointB = list.find(x => x.id === pointBId); const label = map.get("label")[0]; return new LineModel(pointA, pointB, label, id); } }