Skip to content
On this page

Draw the north finger

In the following, we will introduce how to use mxcad plug-in to realize the function of drawing the north pointer in CAD drawings. In this function, the user clicks the canvas to determine the position of the north pointer, and moves the mouse to determine the pointer position and text annotation bit.

Function implementation

  1. Customize the north pointer class

In order to facilitate the later management and modification of the setting of the north pointer, We can through inheritance McDbCustomEntity Customize the entity class to extend the implementation of the custom pointer class. Then, We can use McDbMText or McDbText information text object, instruction pointer to pointer to information on the page.

ts
// Point to the north
class McDbTestCompass extends McDbCustomEntity {
    // Defines point objects inside McDbTestCompass
    // Position point
    private compassPos: McGePoint3d = new McGePoint3d();
    // Pointer to
    private pointerPt: McGePoint3d = new McGePoint3d(this.compassPos.x, this.compassPos.y + this.campassRadius);
    // radius
    private _campassRadius: number = MxFun.screenCoordLong2Doc(20);
    // Word height
    private height: number = this._campassRadius / 4;
    // Text position
    private textPos: McGePoint3d = new McGePoint3d();

    // constructor
    constructor(imp?: any) {
        super(imp);
    }
    // Create the height function
    public create(imp: any) {
        return new McDbTestCompass(imp)
    }
    // Get class name
    public getTypeName(): string {
        return "McDbTestCompass";
    }
    //Sets or gets the pointer radius
    public set campassRadius(val: number) {
        this._campassRadius = val;
    }
    public get campassRadius(): number {
        return this._campassRadius;
    }
    // Read from defined entity data
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.compassPos = filter.readPoint("compassPos").val;
        this.pointerPt = filter.readPoint("pointerPt").val;
        this.textPos = filter.readPoint("textPos").val;
        this._campassRadius = filter.readDouble("campassRadius").val;
        this.height = filter.readDouble("height").val;
        return true;
    }
    // Writes custom entity data
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("pointerPt", this.pointerPt);
        filter.writePoint("compassPos", this.compassPos);
        filter.writePoint("textPos", this.textPos);
        filter.writeDouble("campassRadius", this._campassRadius);
        filter.writeDouble("height", this.height);
        return true;
    }

    // Moves the pinch point of a custom object
    public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
        this.assertWrite();
        const vec = this.pointerPt.sub(this.compassPos)
        const circle = new McDbCircle(this.compassPos.x, this.compassPos.y, this.compassPos.y, this._campassRadius)
        if (iIndex === 0) {
            this.pointerPt.x += dXOffset;
            this.pointerPt.y += dYOffset;
            this.pointerPt.z += dZOffset;
            this.pointerPt = circle.getClosestPointTo(this.pointerPt, false).val;
            const _vec = this.pointerPt.sub(this.compassPos);
            const v = this.textPos.sub(this.compassPos);
            v.rotateBy(_vec.angleTo2(vec, McGeVector3d.kNegateZAxis));
            this.textPos = this.compassPos.clone().addvec(v)
        } else if (iIndex === 1) {
            this.compassPos.x += dXOffset;
            this.compassPos.y += dYOffset;
            this.compassPos.z += dZOffset;
            this.textPos.x += dXOffset;
            this.textPos.y += dYOffset;
            this.textPos.z += dZOffset;
            this.pointerPt.x += dXOffset;
            this.pointerPt.y += dYOffset;
            this.pointerPt.z += dZOffset;
        } else if (iIndex === 2) {
            this.textPos.x += dXOffset;
            this.textPos.y += dYOffset;
            this.textPos.z += dZOffset;
        }
    };
    // Gets the pinch point of a custom object
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray()
        ret.append(this.pointerPt);
        ret.append(this.compassPos);
        ret.append(this.textPos);
        return ret;
    };

    // Draw entity 
    public worldDraw(draw: MxCADWorldDraw): void {
        // Draw pointer disk
        const circle = new McDbCircle(this.compassPos.x, this.compassPos.y, this.compassPos.z, this.campassRadius);
        draw.drawEntity(circle);
        // Draw pointer
        const vec = this.pointerPt.sub(this.compassPos).normalize().mult(this._campassRadius);
        const pt1 = this.compassPos.clone().subvec(vec.rotateBy(Math.PI * (1 / 36)));
        const pt2 = this.compassPos.clone().subvec(vec.rotateBy(Math.PI * 2 * (35 / 36)));
        const solid = new McDbHatch();
        solid.appendLoop(new McGePoint3dArray([pt1, pt2, this.pointerPt]));
        draw.drawEntity(solid);
        // Draw pointer text
        const text = new McDbText();
        text.textString = '';
        text.height = this.height;
        text.horizontalMode = McDb.TextHorzMode.kTextCenter;
        text.position = text.alignmentPoint = this.textPos;
        draw.drawEntity(text);
    }

    // Set the location of the north pointer
    public setCompassPos(pt: McGePoint3d) {
        this.compassPos = pt.clone()
    }
    // Get the location of the north pointer
    public getCompassPos() {
        return this.compassPos;
    }
    // Set to
    public setPointerPt(pt: McGePoint3d) {
        const circle = new McDbCircle(this.compassPos.x, this.compassPos.y, this.compassPos.z, this._campassRadius);
        this.pointerPt = circle.getClosestPointTo(pt, false).val;
        const vec = this.pointerPt.sub(this.compassPos).normalize();
        this.textPos = this.pointerPt.clone().addvec(vec.mult(this._campassRadius/4))
    }
    // Get to
    public getPointerPt() {
        return this.pointerPt;
    }
};
  1. Register custom class information
ts
new McDbTestCompass().rxInit();
  1. Write a method, call McDbTestCompass custom compass class to achieve the extraction of annotation function
  • Set the location of the north pointer

We can use MxCADUiPrPoint() take object set behind the position.

ts
// Set the direction of the north needle
const getPoint1 = new MxCADUiPrPoint();
getPoint1.setMessage('Please set the location of the north pointer:');
const pt1 = await getPoint1.go();
if (!pt1) return;
compass.setCompassPos(pt1);
  • Set the pointer direction Call MxCADUiPrPoint take object set behind the position of the pointer to point, If the user does not set the pointing point, the pointer is set to the positive direction of the Y-axis by default.
ts
// The structure points to the north
const compass = new McDbTestCompass();
// Set pointer direction
const getPoint2 = new MxCADUiPrPoint();
getPoint2.setBasePt(pt1);
getPoint2.setMessage('Please set the north direction:');
// Dynamic drawing pointer
getPoint2.setUserDraw((pt, pw) => {
    const _compass = compass.clone() as McDbTestCompass;
    _compass.setPointerPt(pt);
    pw.drawMcDbEntity(_compass);
    // Draw pointer to
    const line = new McDbLine(pt1.x, pt1.y, pt1.z,pt.x,pt.y,pt.z);
    pw.drawMcDbEntity(line);
});
let pt2 = await getPoint2.go();
// Set default to
if(!pt2){
    pt2 = pt1.clone().addvec(McGeVector3d.kYAxis.clone().mult(compass.campassRadius));
}
compass.setPointerPt(pt2);
// Draw pointer
MxCpp.getCurrentMxCAD().drawEntity(compass);

Functional practice

Practical effects are as follows:

  • Click the Draw the Pointer button to perform the Draw the pointer method
  • Click on the canvas to set the location of the north pointer
  • Move the mouse to set the pointer direction and click the left mouse button to determine the pointing point
  • Successfully drew the compass needle