Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

16 REPLIES 16
SOLVED
Reply
Message 1 of 17
JamesMaeding
717 Views, 16 Replies

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

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() : mostlyHarmless
I'm just here for the Shelties

16 REPLIES 16
Message 2 of 17
Kent1Cooper
in reply to: JamesMaeding

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

Kent Cooper, AIA
Message 3 of 17
JamesMaeding
in reply to: JamesMaeding

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() : mostlyHarmless
I'm just here for the Shelties

Message 4 of 17
JamesMaeding
in reply to: Kent1Cooper

indeed, thanks.

I modified my orig post to include it.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 5 of 17
SEANT61
in reply to: JamesMaeding

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?


************************************************************
May your cursor always snap to the location intended.
Message 6 of 17
JamesMaeding
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() : mostlyHarmless
I'm just here for the Shelties

Message 7 of 17
SEANT61
in reply to: JamesMaeding

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))

 


************************************************************
May your cursor always snap to the location intended.
Message 8 of 17
JamesMaeding
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() : mostlyHarmless
I'm just here for the Shelties

Message 9 of 17
SEANT61
in reply to: JamesMaeding

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.


************************************************************
May your cursor always snap to the location intended.
Message 10 of 17
JamesMaeding
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() : mostlyHarmless
I'm just here for the Shelties

Message 11 of 17
SEANT61
in reply to: JamesMaeding

Just another cad-user/programmer.  I've also spent some time wrangling with this issue.

 

 

 

AutoCAD has a built in protocol imposed upon anyone or anything (including itself)  generating or modifying 2D entities.  The entities will be describes within their own coordinate system, where the Z direction will always be normal to the Plane the entity is parallel to, and the X direction will always be determined by the Arbitrary Axis Algorithm (AAA).

 

Text entities (among others) are particularly dependant on an X axis for complete orientation.  Given that the AAA modifies how the X axis is established based on the Extrusion Vector’s orientation to WCS’s Z, a programmer/routine must compensate if a particular World or UCS orientation is required.  Fortunately, programmers do not have to write their own AAA routines, that is addressed in the trans function

 

 

The beauty of the protocol is that it eliminates ambiguity.  This means that the TEXT entity in my attachment has to have that 210 group value and the 90 rotation.  That orientation can not be replicated with any other variations of those values. *

 

It may be advisable to re-read the thread you linked in post #3 and this one:

http://www.theswamp.org/index.php?topic=13526.0

 

 

 

 

*Notwithstanding the extreme of Extrusion vector mirrored in 3D, and Text Backward (71 . 2)


************************************************************
May your cursor always snap to the location intended.
Message 12 of 17
JamesMaeding
in reply to: SEANT61

I see what you are doing now in how to predict the rotation and adjust. I still am not sure how the AAA works differently when under 1/64 on x or y dir.

I guess you just analye what it does, and adjust for the rotation it spits out.

thanks for hanging with me.

 


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 13 of 17
JamesMaeding
in reply to: JamesMaeding

taking your advice, I added a couple lines to adjust for the rotation:

 

(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.2)
  )
  (command "line" pt1 pt2 "")
  ;DRAW TEXT
  ;START BY GETTING NORMAL VECTOR TO PLANE OF LINE AS IF IT WAS A FLAT ROAD
  (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)
  )

  ;FIGURE ROTATION OF 3D ITEM RELATIVE TO WCS
  (SETQ VEC2 (trans '(1.0 0.0 0.0) UNITVEC 0 1))
  ;LOOK AT ANGLE IN XY PLAN
  (SETQ ANG (* -1.0 (ATAN (/ (CADR VEC2)(CAR VEC2)))))


  ;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 ANG) ;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)
)

 It works, and I hope I did not give away more than you wanted to.

I did an ADN support request on this and no answer at all yet. Its one that I knew had a solution too, my other ADN items have been more obscure...

thanks again.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 14 of 17
SEANT61
in reply to: JamesMaeding

“I hope I did not give away more than you wanted to.”

 

Absolutely not.  I would have like to give more but I don’t know AutoLisp very well.  I’m more of a VBA/.NET guy.  The same situation is present in those languages, also.  As a matter of fact, this thread shows the exact time when the fog cleared for me:

 

http://forums.autodesk.com/t5/Visual-Basic-Customization/Inserting-Block-w-Custom-UCS/m-p/2159881/hi...


************************************************************
May your cursor always snap to the location intended.
Message 15 of 17
JamesMaeding
in reply to: SEANT61

Cool. I am currently mixing lisp with .net, but much prefer .net coding.

Lisp is 10x simpler to maintain though, as the API does not change as much as .net, and the debugging does not require waiting for acad to start every time.

 


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 16 of 17
JamesMaeding
in reply to: SEANT61

the fruits of our labor...


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 17 of 17
SEANT61
in reply to: JamesMaeding

That looks good.


************************************************************
May your cursor always snap to the location intended.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost