Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Distinguished Contributor
jmaeding
Posts: 1,046
Registered: ‎12-27-2006
Message 1 of 17 (330 Views)
Accepted Solution

small tilts from XY plane of text cause entmake to not behave

330 Views, 16 Replies
05-02-2012 11:32 AM

I did a routine to place text along a 3d polyline, using entmake for speed.

I noticed when the slope of the segment being labeled was less than 1.6%, the text gets drawn at some odd rotation angle.

 

I put together this test function 3DText, and you can modify the z value of pt2 to see the effect.

 

(DEFUN C:3DTEXT ( / PT1 PT2 DST INSPOINT NORMVEC TLIST UNITVEC X)
  ;DRAW LINE AT 1% SLOPE
  (SETQ PT1 (LIST 0.0 0.0 0.0)
        PT2 (LIST 100.0 0.0 1.0)
  )
  (command "line" pt1 pt2 "")
  ;DRAW TEXT
  ;START BY GETTING NORMAL VECTOR TO PLANE OF LINE AS IF IT WAS A FLAT ROAD
  ;(SETQ NORMVEC  (CDR (ASSOC 210 (ENTGET (CAR (ENTSEL))))));'(-0.0099995 0.0 0.99995))
  (SETQ NORMVEC (NORMVEC-FROM-2PTS PT1 PT2))

  ;NOW MAKE UNIT VECTOR OF NORMVEC IN CASE NOT ALREADY
  (SETQ DST (DISTANCE '(0.0 0.0 0.0) NORMVEC)
        UNITVEC (MAPCAR '(LAMBDA ( X ) (/ X DST)) NORMVEC)
        INSPOINT (TRANS PT1 1 UNITVEC)
  )

  ;DRAW TEXT LEFT JUSTIFIED
  (SETQ TLIST (LIST
                (CONS 0 "TEXT")
                (CONS 100 "AcDbEntity")
                (CONS 67 0)
                (CONS 410 "Model")
                (CONS 8 "0")
                (CONS 62 7)
                (CONS 100 "AcDbText")
                (CONS 10 INSPOINT)
                (CONS 40 4.0)
                (CONS 1 "ABCD")
                (CONS 50 0.0) ;ROTATION
                (CONS 41 1.0)
                (CONS 51 0.0)
                (CONS 7 "STANDARD")
                (CONS 71 0)
                (CONS 72 0)
                (CONS 11 (LIST 0.0 0.0 0.0))
                (CONS 210 UNITVEC)
                (CONS 100 "AcDbText")
                (CONS 73 0)
              )
  )
  (ENTMAKE TLIST)
  (PRINC)
)

;GET NORMAL VECTOR FROM TWO POINTS AS IF THEY FORM A FLAT ROAD
;MEANT FOR FEEDING INTO DRAW TEXT 3D FUNCTION
;(NORMVEC-FROM-2PTS '(0.0 0.0 0.0) '(100.0 0.0 1.0))
(DEFUN NORMVEC-FROM-2PTS (PT1 PT2 / 2DLEN SIDEPT PLANE NORMPT NORMVEC)
  ;FIND THE THIRD POINT BY GOING 90 DEG TO RIGHT FROM ANGLE OF PT1 AND PT2
  (SETQ 2DLEN (DISTANCE (MAKEPT2D PT1) (MAKEPT2D PT2))
        SIDEPT (POLAR PT1 (- (ANGLE PT1 PT2) (/ PI 2.0)) 2DLEN)
        ;MAKE A PLANE LIST (A B C D)
        PLANE (GET-PLANE-3PTS PT1 PT2 SIDEPT)
        ;GET A POINT NORMAL TO THAT PLANE
        NORMPT (GET-3DPOINT-NORMAL PT1 10.0 PLANE)
        ;GET THE VECTOR TO THAT POINT FROM PT1
        NORMVEC (MAPCAR '- NORMPT PT1)
  )
  NORMVEC
)

;GET EQUATION OF PLANE FROM 3 POINTS
;EQUATION IS Ax + By + Cz + D = 0
;YOU CAN USE TO PREDICT Z FROM X AND Y BY ISOLATING Z:
;Z = (-D-AX-BY) / C
;THE NORMAL VEC IS ABC
;
;NOTE THAT IF YOU PLUG IN 0 FOR X AND Y, YOU GET Z = -D/C
;(SETQ PLANE (GET-PLANE-3PTS (LIST 10.0 0.0 0.0)(LIST 10.0 10.0 10.0)(LIST 0.0 10.0 10.0)))
;(SETQ PLANE (GET-PLANE-3PTS (GETPOINT)(GETPOINT)(GETPOINT)))
(DEFUN GET-PLANE-3PTS (PT1 PT2 PT3 / A B C D)
  ;A = y1 (z2 - z3) + y2 (z3 - z1) + y3 (z1 - z2) 
  ;B = z1 (x2 - x3) + z2 (x3 - x1) + z3 (x1 - x2) 
  ;C = x1 (y2 - y3) + x2 (y3 - y1) + x3 (y1 - y2) 
  ;- D = x1 (y2 z3 - y3 z2) + x2 (y3 z1 - y1 z3) + x3 (y1 z2 - y2 z1)

  (SETQ A (+ (* (CADR PT1)(- (CADDR PT2)(CADDR PT3)))
             (* (CADR PT2)(- (CADDR PT3)(CADDR PT1)))
             (* (CADR PT3)(- (CADDR PT1)(CADDR PT2)))
          )
        B (+ (* (CADDR PT1)(- (CAR PT2)(CAR PT3)))
             (* (CADDR PT2)(- (CAR PT3)(CAR PT1)))
             (* (CADDR PT3)(- (CAR PT1)(CAR PT2)))
          )
        C (+ (* (CAR PT1)(- (CADR PT2)(CADR PT3)))
             (* (CAR PT2)(- (CADR PT3)(CADR PT1)))
             (* (CAR PT3)(- (CADR PT1)(CADR PT2)))
          )
        D (* -1.0 (+ (* (CAR PT1)(- (* (CADR PT2)(CADDR PT3))(* (CADR PT3)(CADDR PT2))))
                     (* (CAR PT2)(- (* (CADR PT3)(CADDR PT1))(* (CADR PT1)(CADDR PT3))))
                     (* (CAR PT3)(- (* (CADR PT1)(CADDR PT2))(* (CADR PT2)(CADDR PT1))))
                  )
          )
  )
  (LIST A B C D)
)

;GET POINT FROM START POINT AND DISTANCE IN NORMAL DIRECTION TO SURFACE
;A NEGATIVE DISTANCE GIVES A POINT WITH LOWER Z THAN START POINT
;(COMMAND "LINE" (SETQ STPT (GETPOINT))(GET-3DPOINT-NORMAL STPT -10.0 PLANE) "")
(DEFUN GET-3DPOINT-NORMAL (STPT DIST PLANE / LEN RET ZLIFT)
  ;GET NORMAL LENGTH
  (SETQ LEN (EXPT (+ (EXPT (NTH 0 PLANE) 2.0)(EXPT (NTH 1 PLANE) 2.0)(EXPT (NTH 2 PLANE) 2.0)) 0.5))
  ;TEST FOR POSITIVE DIRECTION
  (SETQ ZLIFT (* (NTH 2 PLANE) (/ DIST LEN)))
  (IF (OR (AND (> DIST 0.0)(< ZLIFT 0.0))
          (AND (< DIST 0.0)(> ZLIFT 0.0))
      )
    (SETQ RET (LIST (- (CAR STPT)(* (NTH 0 PLANE) (/ DIST LEN)))
                    (- (CADR STPT)(* (NTH 1 PLANE) (/ DIST LEN)))
                    (- (CADDR STPT) ZLIFT)
              )
    )
    (SETQ RET (LIST (+ (CAR STPT)(* (NTH 0 PLANE) (/ DIST LEN)))
                    (+ (CADR STPT)(* (NTH 1 PLANE) (/ DIST LEN)))
                    (+ (CADDR STPT) ZLIFT)
              )
    )
  )
  RET
)

(DEFUN MAKEPT2D (PT / )
  (IF PT
    (LIST (CAR PT)(CADR PT) 0.0)
  )
)

 

 

 That code is not all by me, but collected from the internet, I will be happy to credit anyone recognizing portions.

It is very useful code for doing several things such as setting up a UCS to three points in space.

In this case, I am just using it to get the normal vector to a segment.

 

What you will see is the text behaving when z val of pt 2 is 1.6 or above.

Does this have something to do with the 1/64th rule I recall reading about for extrusion vectors?

Something like if its almost normal to xy plane, a different method is used.

I drew the text at slope of 1.0% by hand, and it had the same 210 group I am trying to make here.

Clearly, the plane I am trying to use is rotated in some way and that rotates the text when viewed from the top.

thx

internal protected virtual unsafe Human()
http://onesmallstepforcad.com/

If we consider the situation you demoed in the original post, where you would like to see the text running parallel to the X axis, then this is one possible solution:

 

trans a vector 1.0,0.0,0.0 from the OCS to WCS. 

            For example –

            Command: (trans '(1.0 0.0 0.0) '(-0.015998 -9.79592e-019 0.999872) 0 1)

            (6.12322e-017 -1.0 0.0)

 

Determine the resultant vector’s  angle from the X axis.  Negate that value, and assign it to the rotation property.

*Expert Elite*
Kent1Cooper
Posts: 5,868
Registered: ‎09-13-2004
Message 2 of 17 (327 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-02-2012 11:43 AM in reply to: jmaeding

[You need to include the (MAKEPT2D) function, if not also perhaps some other(s) -- that's the one in the error message.]

Kent Cooper
Distinguished Contributor
jmaeding
Posts: 1,046
Registered: ‎12-27-2006
Message 3 of 17 (326 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-02-2012 11:47 AM in reply to: jmaeding

this post explains that the extrusion vector numbers must be larger than 1/64 for x andf y:

http://www.theswamp.org/index.php?topic=31802.msg373035#msg373035

 

It says:

"...if the extrusion vector is not pointing in a direction which is very close to the Z axis, the X axis of the OCS is just the WCS Z axis crossed with the extrusion vector. You can't use this when the extrusion vector is too close to the Z axis because of numerical accuracy and because it degenerates completely if they are equal. So, if it is close, then the OCS X axis is the WCS Y axis crossed with the extrusion vector. The test for closeness is if both the X and Y coordinates of the extrusion vector are less then 1/64. The extrusion vector is normalized, which means its length is 1, which is why you can use a fixed number like 1/64. According the AutoCAD documentation, the reason 1/64 is used is because its decimal representation terminates after 6 digits, 0.015625, and it also equals 2^-6, which means in binary decimal it is 0.000001, which also has 6 digits. As far as the other two axes, the Z coordinate of the OCS is the extrusion direction and the Y direction is Z crossed with X, the usual right hand rule."

 

I am not sure what to do with that though.

The fact that an entity drawn by hand matches the values I am trying to use with entmake, confuses me.

I even grabbed the 210 group from the hand drawn entity as a test, same result.

How should I construct the 210 group for almost flat planes?

internal protected virtual unsafe Human()
http://onesmallstepforcad.com/

Distinguished Contributor
jmaeding
Posts: 1,046
Registered: ‎12-27-2006
Message 4 of 17 (324 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-02-2012 11:49 AM in reply to: Kent1Cooper

indeed, thanks.

I modified my orig post to include it.

internal protected virtual unsafe Human()
http://onesmallstepforcad.com/

Distinguished Contributor
SEANT61
Posts: 137
Registered: ‎09-23-2008
Message 5 of 17 (306 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-02-2012 03:10 PM in reply to: jmaeding

AutoCAD compensates while drawing by hand.  The “hand drawn”, and the entity made via your program may have the same 210 group value, but what is the rotation Property of the hand drawn version?

Distinguished Contributor
jmaeding
Posts: 1,046
Registered: ‎12-27-2006
Message 6 of 17 (306 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-02-2012 03:31 PM in reply to: SEANT61

its 0 (50 group), so nothing odd there:

 

(-1 . <Entity name: 7ffffb13440>)
(0 . "TEXT")
(330 . <Entity name: 7ffffb039f0>)
(5 . "A8C")
(100 . "AcDbEntity")
(67 . 0)
(410 . "Model")
(8 . "0")
(100 . "AcDbText")
(10 0.0 0.0 0.0)
(40 . 1.45819)
(1 . "sdfgzsdfsd")
(50 . 0.0)
(41 . 1.0)
(51 . 0.0)
(7 . "Standard")
(71 . 0)
(72 . 0)
(11 0.0 0.0 0.0)
(210 -0.0099995 0.0 0.99995)
(100 . "AcDbText")
(73 . 0)

 

internal protected virtual unsafe Human()
http://onesmallstepforcad.com/

Distinguished Contributor
SEANT61
Posts: 137
Registered: ‎09-23-2008
Message 7 of 17 (301 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-02-2012 04:14 PM in reply to: jmaeding

I set the parameters of your routine as you suggested, with a Z value of 1.6, and got what you see at top. See Attachment

 

I then set a UCS to match the Extrusion Direction of the oddly rotated text.  I then added text by hand, from the command line, and the text appeared with the correct rotation (see the text at 0,0,0).  But if we look at the properties, the text has a Rotation property of 90 degrees.

 

 

 

Via routine:

((0 . "TEXT") (330 . <Entity name: 7ffff6229f0>) (5 . "225")

(100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (62 . 7) (100 .

"AcDbText") (10 -37.3205 5.83719e-015 -9.3395e-017) (40 . 4.0) (1 . "ABCD") (50

. 0.0) (41 . 1.0) (51 . 0.0) (7 . "Standard") (71 . 0) (72 . 0) (11 0.0 0.0

-9.3395e-017) (210 -0.015998 -9.79592e-019 0.999872) (100 . "AcDbText") (73 .

0))

 

 

Via command:

((0 . "TEXT") (330 . <Entity name: 7ffff6229f0>) (5 . "228") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbText") (10 0.0 0.0 0.0) (40 . 4.0) (1 . "ABCD") (50 . 1.5708) (41 . 1.0) (51 . 0.0) (7 . "Standard") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (210 -0.015998 4.87127e-016 0.999872) (100 . "AcDbText") (73 . 0))

 

Distinguished Contributor
jmaeding
Posts: 1,046
Registered: ‎12-27-2006
Message 8 of 17 (294 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-02-2012 05:19 PM in reply to: SEANT61

I think you are on the right track, but you did a test on text at 1.6% only.

To see what I am seeing, try it with z = 1.0, the text is rotated different than at 1.6%.

 

I think you are seeing the end result of how acad handles almost flat items differently, but what is it doing?

How does it determine the rotation angle for those almost flat situaitons?

Its not some even number, as I am seeing odd rotations for different slopes.

 

I'm wondering if that is just an effect though, and the right way to do this is switch gears when the x or y is less than 1/64.

The other posts explain it, but I cannot seem to comprehend what they are saying.

Its like pieces that I get individually, but not what to do with them. I did the math in Engineering school, its not obvious to me though so far.

internal protected virtual unsafe Human()
http://onesmallstepforcad.com/

Distinguished Contributor
SEANT61
Posts: 137
Registered: ‎09-23-2008
Message 9 of 17 (279 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-03-2012 01:17 AM in reply to: jmaeding

If we consider the situation you demoed in the original post, where you would like to see the text running parallel to the X axis, then this is one possible solution:

 

trans a vector 1.0,0.0,0.0 from the OCS to WCS. 

            For example –

            Command: (trans '(1.0 0.0 0.0) '(-0.015998 -9.79592e-019 0.999872) 0 1)

            (6.12322e-017 -1.0 0.0)

 

Determine the resultant vector’s  angle from the X axis.  Negate that value, and assign it to the rotation property.

Distinguished Contributor
jmaeding
Posts: 1,046
Registered: ‎12-27-2006
Message 10 of 17 (266 Views)

Re: small tilts from XY plane of text cause entmake to not behave

05-03-2012 08:57 AM in reply to: SEANT61

couple questions:

1) are you responding due to my ADN request, which is the same as a subscription support request, but with "API help" items selected?

I ask as I used to get an email when a response was posted. I'm guessing not, and you are just helping unpaid which I thank you for.

 

2) Is your solution based on understanding the alternate method for finding 210 group when almost flat to xy plane, or just observing results and doing what is needed to adjust? Both are valuable to be sure, and a solution is primary to me.

I'm essentially wondering if there are several solutions, and yours is one that gives the same end result, but has a rotation involved.

Maybe your example was ment to show me even acad adds a rotation in the almost flat case. Did I miss that?

 

I don't mean to confuse things by adding 90 deg to get text to follow a line. We can add any rotation once we establish a function that correctly draws text given any normal vector.

thanks a bunch

internal protected virtual unsafe Human()
http://onesmallstepforcad.com/

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.