问题
I have a Triangle as a polyline and I want to draw an Altitude. I give the command "line"
or "_line"
the right points but AutoCAD draws the line from the vertex to the adjacent vertex.
It's not just in AutoLISP, AutoCAD won't let me draw a line from a vertex to the middle of an edge in a polyline.
How can I do that?
I thought of adding a vertex in the polyline, but this didn't help that much. I tried to add connector: a circle or another object close enough to the line and connect the altitude to it, but that didn't help either.
Any suggestions?
回答1:
Firstly, I suspect that the issue with your current attempts is the influence of active Object Snap modes when supplying points to the LINE
command.
There are several ways to avoid this:
1. Use the "None" Object Snap modifier
When supplying points to an AutoCAD command through an AutoLISP command
expression, you can avoid the effect of any active Object Snap modes by preceding the point with the none
or non
Object Snap modifier.
This is similar to how you might precede a point with end
to force the activation of the Endpoint Object Snap modifier, but in this case, none
or non
means "ignore all Object Snap modes". The full list of available prefixes may be found here.
Here is an example of this method:
(setq p '(0.0 0.0 0.0)
q '(1.0 1.0 0.0)
)
(command "_.line" "_non" p "_non" q "")
A few notes on the above:
The underscore prefixes
_
(as used in"_.line"
and"_non"
) cause AutoCAD to interpret the input as non-localised command input (i.e. English), else, if such input were supplied to a non-English version of AutoCAD, it may carry another meaning in the non-English language.The dot/period prefix
.
(as used in"_.line"
) causes AutoCAD to always use the original definition of the command, and not a redefined version (as may exist if the user has used the UNDEFINE command).
2. Temporarily Disable Object Snap
Whilst the above method acknowledges that there may be active Object Snap modes, forcing such modes to be ignored for every point input, if you are issuing many command calls involving numerous point inputs, you may find it cleaner to simply temporarily disable Object Snap altogether, and then reenable the previously active modes following completion of your program.
The obvious way to achieve this would be to store the current value of the OSMODE
system variable, set such system variable to 0
before issuing your command
expression, and then reset the OSMODE
system variable to its previous value, e.g.:
(setq p '(0.0 0.0 0.0)
q '(1.0 1.0 0.0)
m (getvar 'osmode) ;; Store current OSMODE
)
(setvar 'osmode 0) ;; Set OSMODE to 0 (disables all snaps)
(command "_.line" p q "")
(setvar 'osmode m) ;; Reset OSMODE to stored value
However, this method has the disadvantage that if an error occurs during the time in which OSMODE
is set to 0
, in the absence of an appropriate error handler, OSMODE
will remain equal to 0
and the user will be apoplectic when they discover they have lost their Object Snap settings.
Therefore, a more 'graceful' way to temporarily disable OSMODE
is to make use of bit 16384 which, when set, indicates that Object Snap has been turned off.
Now, rather than using an if
statement to test whether bit 16384
is present in the OSMODE
value, and if so, subtract it from the value, we can make use of the AutoLISP logior
(inclusive bitwise OR
) function to account for both scenarios in a single expression:
(setvar 'osmode (logior 16384 (getvar 'osmode)))
This will return the result of a bitwise inclusive OR
operation between bit 16384
and the current value of the OSMODE
system variable. Therefore, if 16384
is already present in the value, it will be returned, else it will be added.
This can be implemented as follows:
(setq p '(0.0 0.0 0.0)
q '(1.0 1.0 0.0)
m (getvar 'osmode) ;; Store current OSMODE
)
(setvar 'osmode (logior 16384 m)) ;; Turn off Object Snap
(command "_.line" p q "")
(setvar 'osmode m) ;; Reset OSMODE to stored value
Now, if the code encounters an error whilst Object Snap is turned off, the Object Snap settings are not lost - the user may simply need to turn Object Snap back on using F3.
3. Avoid Command Calls Altogether
Of course, the most bulletproof way of avoiding the influence of Object Snap on command point input is to avoid commands entirely!
Instead, you can use the entmake or entmakex function to append the DXF data to the drawing database directly:
(setq p '(0.0 0.0 0.0)
q '(1.0 1.0 0.0)
)
(entmake (list '(0 . "LINE") (cons 10 p) (cons 11 q)))
Or, you can follow the Visual LISP ActiveX route and use the AddLine method of the relevant Block container, e.g. to create a Line in Modelspace you might use:
(vl-load-com)
(setq p '(0.0 0.0 0.0)
q '(1.0 1.0 0.0)
)
(vla-addline
(vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
(vlax-3D-point p)
(vlax-3D-point q)
)
来源:https://stackoverflow.com/questions/57253997/drawing-line-close-to-polyline