Skip to content
On this page

Draw the axis of symmetry

Below we will introduce how to use mxcad plug-in to achieve the function of drawing the symmetry axis in the CAD drawing, in which the user can set the length of the symmetry axis, click the canvas to determine the starting position of the symmetry axis.

Function implementation

  1. Realize custom symmetry axis class

In order to facilitate later management and modify the symmetry axis Settings, We can through inheritance McDbCustomEntity Custom entity class to extend the implementation of custom symmetry axis class.

ts
// Symmetry axis class
class McDbTestAxisOfSymmetry extends McDbCustomEntity {
    // Defines the object inside McDbTestAxisOfSymmetry 
    // The point at which the axis of symmetry begins
    private startPoint: McGePoint3d = new McGePoint3d();
    // End point of the axis of symmetry
    private endPoint: McGePoint3d = new McGePoint3d();
    // Symmetry axis mark pinch point
    private midPt: McGePoint3d = new McGePoint3d();
    private movePt: McGePoint3d = new McGePoint3d();
    private tPoint: McGePoint3d = new McGePoint3d();
    // Symmetry axis length
    private _axisLength: number = 0;

    // constructor
    constructor(imp?: any) {
        super(imp);
    }
    // Create function
    public create(imp: any) {
        return new McDbTestAxisOfSymmetry(imp)
    }
    // Get class name
    public getTypeName(): string {
        return "McDbTestAxisOfSymmetry";
    }
    // Read from defined entity data
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.startPoint = filter.readPoint("startPoint").val;
        this.endPoint = filter.readPoint("endPoint").val;
        this.midPt = filter.readPoint("midPt").val;
        this.movePt = filter.readPoint("movePt").val;
        this.tPoint = filter.readPoint("tPoint").val;
        this._axisLength = filter.readDouble("axisLength").val;
        return true;
    }
    // Writes custom entity data
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("startPoint", this.startPoint);
        filter.writePoint("endPoint", this.endPoint);
        filter.writePoint("midPt", this.midPt);
        filter.writePoint("movePt", this.movePt);
        filter.writePoint("tPoint", this.tPoint);
        filter.writeDouble("axisLength", this._axisLength);
        return true;
    }

    // Moves the pinch point of a custom object
    public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
        this.assertWrite();
        const l1 = this.startPoint.distanceTo(this.midPt)
        const l2 = this.movePt.distanceTo(this.midPt)
        const l3 = this.midPt.distanceTo(this.tPoint)
        if (iIndex === 0) {
            this.startPoint.x += dXOffset;
            this.startPoint.y += dYOffset;
            this.startPoint.z += dZOffset;
            // Recalculate the pinch position
            this.getMovePoints(l1, l2, l3);
        } else if (iIndex === 1) {
            this.endPoint.x += dXOffset;
            this.endPoint.y += dYOffset;
            this.endPoint.z += dZOffset;
            // Recalculate the pinch position
            this.getMovePoints(l1, l2, l3);
        } else if (iIndex === 2) {
            const _midPt = this.midPt.clone();
            _midPt.x += dXOffset;
            _midPt.y += dYOffset;
            _midPt.z += dZOffset;
            const line = new McDbLine(this.startPoint, this.endPoint);
            const res = line.getClosestPointTo(_midPt, false);
            const l = line.getLength()?.val / 2 - this.midPt.distanceTo(this.movePt)
            if (res.val && this.startPoint.distanceTo(res.val) <= l) {
                const x = res.val.x - this.midPt.x;
                const y = res.val.y - this.midPt.y;
                const z = res.val.z - this.midPt.z;
                this.midPt = res.val;
                this.movePt.x += x;
                this.movePt.y += y;
                this.movePt.z += z;
                this.tPoint.x += x;
                this.tPoint.y += y;
                this.tPoint.z += z;
            }
        } else if (iIndex === 3) {
            const _movePt = this.movePt.clone();
            _movePt.x += dXOffset;
            _movePt.y += dYOffset;
            _movePt.z += dZOffset;
            const line = new McDbLine(this.startPoint, this.endPoint);
            const res = line.getClosestPointTo(_movePt, false);
            const l = res.val?.distanceTo(this.startPoint)
            if (l <= line.getLength().val / 2) {
                this.movePt = res.val;
            }
        } else if (iIndex === 4) {
            const _tPoint = this.tPoint.clone();
            _tPoint.x += dXOffset;
            _tPoint.y += dYOffset;
            _tPoint.z += dZOffset;
            const line = new McDbLine(this.midPt, this.tPoint);
            const res = line.getClosestPointTo(_tPoint, true);
            this.tPoint = res.val;
        }
    };
    private getMovePoints(l1: number, l2: number, l3: number) {
        let startPt, endPt;
        if (this.startPoint.x < this.endPoint.x) {
            startPt = this.startPoint.clone();
            endPt = this.endPoint.clone();
        } else {
            startPt = this.endPoint.clone();
            endPt = this.startPoint.clone();
        }
        if (this.endPoint.distanceTo(this.startPoint) < (l1 + l2) * 2) {
            const v = this.endPoint.sub(this.startPoint).normalize();
            endPt = this.startPoint.addvec(v.clone().mult((l1 + l2) * 2));
        }
        const vec = endPt.sub(startPt).normalize();
        this.midPt = startPt.clone().addvec(vec.clone().mult(l1));
        this.movePt = this.midPt.clone().addvec(vec.clone().mult(l2));
        this.tPoint = this.midPt.clone().addvec(vec.clone().perpVector().mult(l3));
        this.endPoint = endPt;
        this.startPoint = startPt;
    }
    // Gets the pinch point of a custom object
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray()
        ret.append(this.startPoint);
        ret.append(this.endPoint);
        ret.append(this.midPt);
        ret.append(this.movePt);
        ret.append(this.tPoint);
        return ret;
    };

    // Draw entity 
    public worldDraw(draw: MxCADWorldDraw): void {
        if (!this._axisLength) this._axisLength = MxFun.screenCoordLong2Doc(10);
        this.drawAxiosIcon().forEach(entity => {
            draw.drawEntity(entity);
        })
        const pl = new McDbPolyline();
        pl.addVertexAt(this.startPoint);
        pl.addVertexAt(this.endPoint);
        draw.drawEntity(pl);
    }

    // Draw the symmetry axis
    private drawAxiosIcon(): McDbEntity[] {
        let startPt, endPt;
        if (this.startPoint.x < this.endPoint.x) {
            startPt = this.startPoint.clone();
            endPt = this.endPoint.clone();
        } else {
            startPt = this.endPoint.clone();
            endPt = this.startPoint.clone();
        }
        if (this.midPt.distanceTo(this.movePt) == 0) {
            this.getMovePoints(this._axisLength / 2, this._axisLength * (5 / 8), this._axisLength);
        }
        const pt2 = this.midPt.clone().addvec(this.midPt.sub(this.tPoint));
        const line1 = new McDbLine(this.tPoint, pt2);
        const line2 = line1.clone() as McDbLine;
        line2.move(this.midPt, this.movePt);
        const _midPt = endPt.clone().subvec(this.midPt.sub(startPt));
        const line3 = line1.clone() as McDbLine;
        const line4 = line2.clone() as McDbLine;
        line3.move(this.movePt, _midPt);
        line4.move(this.movePt, _midPt);
        return [line1, line2, line3, line4]
    }

    // Set the start point of the symmetry axis
    public setStartPoint(pt: McGePoint3d) {
        this.startPoint = pt.clone();
    }
    // Get the start point of the symmetry axis
    public getStartPoint() {
        return this.startPoint;
    }
    // Set the end point of the symmetry axis
    public setEndPoint(pt: McGePoint3d) {
        this.endPoint = pt.clone()
    }
    // Obtain the end point of the symmetry axis
    public getEndPoint() {
        return this.endPoint;
    }
};
  1. Register custom class information
ts
new McDbTestAxisOfSymmetry().rxInit();
  1. Write a method, call McDbTestAxisOfSymmetry custom symmetry class to achieve the extraction annotation function
  • Set the starting point of the symmetry axis

Call MxCADUiPrPoint take object set position, the starting point of the axis of symmetry.

ts
// Construct the symmetry axis object
const axis = new McDbTestAxisOfSymmetry();
// Set the starting point of the symmetry axis
const getPoint1 = new MxCADUiPrPoint();
getPoint1.setMessage('Please set the starting point of the symmetry axis:');
const pt1 = await getPoint1.go();
if (!pt1) return;
axis.setStartPoint(pt1);
// Set the end point of the symmetry axis
const getPoint2 = new MxCADUiPrPoint();  
getPoint2.setMessage('Please set the end point of the symmetry axis:');
// Dynamically draw the axis of symmetry
getPoint2.setUserDraw((pt, pw) => {
    const _axis = axis.clone() as McDbTestAxisOfSymmetry;
    _axis.setEndPoint(pt);
    pw.drawMcDbEntity(_axis);
});
const pt2 = await getPoint2.go();
if (!pt2) return;
axis.setEndPoint(pt2);
// Draw entity
MxCpp.getCurrentMxCAD().drawEntity(axis);

Functional practice

Practical effects are as follows:

  • Click the Draw Symmetry Axis button to perform the Draw symmetry axis method
  • Click the left mouse button to set the starting point of the symmetry axis
  • The break line was successfully drawn
  • Move the symmetry axis pinch point to set the symmetry axis style and position