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

Offset Ellipses, with starting/ending angles question

18 REPLIES 18
SOLVED
Reply
Message 1 of 19
Kent1Cooper
2754 Views, 18 Replies

Offset Ellipses, with starting/ending angles question

I have written a routine [attached for those who can use it as is] that offsets an Ellipse so that the result is also a true Ellipse, with the offset distance being used as the distance between the quadrant point locations of the original and resultant Ellipses.

 

Yes, I know the original and the result are not equidistant everywhere, which is why regular Offset produces a Spline rather than an Ellipse.  And the eccentricity of the new Ellipse will be different from that of the original.  But there have been several threads, on this website and elsewhere, asking to do this.  I found a limited version here that offsets to the wrong side under certain circumstances, and some suggested work-arounds, and apparently AutoDesk Inventor can do it, but I haven't seen a real solution for AutoCAD.

 

Anyway, the offsetting of full Ellipses seems to be working well, including in other-than-World coordinate systems.  But I want it to be able to offset elliptical arcs [partial Ellipses] as well.  So I made the routine impose the numbers for the starting and ending angles [association-list codes 41 & 42] from the original onto the resultant.  That's easy enough, but for starting and ending angle values that are not in the quadrant directions, the result's end is not at the same angle from the center as in the original.

 

See the attached image.  The yellow elliptical arc is the original one, defined with a start angle of 45 degrees [the cyan line] and end angle of 270 degrees.  The offset results are red.  Their end angles align properly, I think because that's a quadrant direction.  But their starting angles don't end up at 45 degrees from the center, as I would prefer and as shown in the partial reduced version in the lower right corner.

 

Those ends do align, however, along the green line, and that does in fact run at the angle of the (assoc 41) value in the entity data.  Even though the starting angle for the original was defined as 45 degrees, that is not the equivalent of the radian value in (assoc 41).

 

Does anyone know what the (assoc 41) value actually represents?  It isn't a direction from any obvious location [the center, a focus, an end of the minor axis] -- see the dotted extension of the green line.  I imagine it has something to do with some trig function relating the actual angle from the center to something like the eccentricity.  If I knew what it is, I hope I could put in a calculation to adjust it for the resulting elliptical arc, so that its angle from the center would be the same as the original's.

 

[Then there's the much more complicated issue of getting it to have the "Through" option that regular Offset has.  My son the mathematician tells me calculating the axes from a point that might be anywhere would require solving a fourth-degree polynomial equation, which apparently can't be done with precision.  So it may involve approximating, testing the result, adjusting and approximating again, etc., until it's "close enough," to whatever precision is needed.  I'm thinking about that....]

Kent Cooper, AIA
18 REPLIES 18
Message 2 of 19

Kent, see an explanation of the association of the ellipse 41 at this link:

 

http://www.jefferypsanders.com/autolispexp_enti.html#Ellipse

Message 3 of 19
_gile
in reply to: rogerio_brazil

Hi,

 

It's quite difficult for me to give a plain explaination in English.

But you can see in the attached picture what's an ellipse start parameter (or more generally, an ellipse parameter).

In green the start angle measured about the major axis, in red the corresponding parameter.

You can see the ellipse start point is the intersection between:

- the projection of the intersection of the parameter line and the circumscribed circle parallely to minor axis

- and the projection of the intersection of the parameter line and the inscribed circle parallely to major axis

And  the ratio beween the parameter tangent and the angle tangent is equal to the ratio between the major and minor axis.

 

Here's an AutoLISP example which returns the angle corresponding to the ellipse parameter (more or less 2 * pi)

 

 

(defun EllipseParamToAngle (ellipse param / elst)
  (cond
    ((= 1 (sin param)) (* pi 0.5))
    ((= -1 (sin param)) (* pi 1.5))
    ((+
       (atan
     (* (cdr (assoc 40 (entget ellipse)))
        (/ (sin param) (cos param))
     )
       )
       (if (minusp (cos param))
     pi
     0.0
       )
     )
    )
  )
)

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 19

Hi Gile,

 

Very interesting.

 

I know that Kent is the main party concerned, but it would be possible to calculate precisely the point (or distance) if we used

 

the offset option Through (in any ellipse angle), using any concept that

 

shows the drawing you sent (using the internal circle, the external circle, etc)?

 

Thanks,

Message 5 of 19
Kent1Cooper
in reply to: Kent1Cooper

Thanks for the other replies, which I will investigate, but I found an OOPS in my routine [an incorrect assumption about the nature of the (assoc 11) first axis endpoint designation], so it may not always work right until I fix that [though under some circumstances it will].  I also now have it matching color, linetype, linetype scale and lineweight if they're not default/Bylayer, and highlighting the selected Ellipse while you pick which side you want it offset to, none of which it did before.  I'll post it with those improvements after I've fixed the other thing.

 

I also found another way to get the arc endpoints right, simply using the Arc option in the Ellipse command and the start- and end-points of the source.  But I'm still interested in the mathematical relationship, so I'll check out those links, etc.

Kent Cooper, AIA
Message 6 of 19

Hi Kent,

 

I maked small modifications, like to hihlight ellipse and show the side of the offset, just to tests.

Message 7 of 19
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:

....I found an OOPS in my routine ..., so it may not always work right until I fix that....  I also now have it matching color, linetype, linetype scale and lineweight if they're not default/Bylayer, and highlighting the selected Ellipse while you pick which side you want it offset to....  I'll post it with those improvements after I've fixed the other thing.

 

I also found another way to get the arc endpoints right, simply using the Arc option in the Ellipse command and the start- and end-points of the source.  ....


This seems to work correctly, and also includes those other upgrades.

Kent Cooper, AIA
Message 8 of 19
Kent1Cooper
in reply to: _gile


@_gile wrote:

....you can see in the attached picture what's an ellipse start parameter (or more generally, an ellipse parameter).

....You can see the ellipse start point is the intersection between:

- the projection of the intersection of the parameter line and the circumscribed circle parallely to minor axis

- and the projection of the intersection of the parameter line and the inscribed circle parallely to major axis

 

... AutoLISP example which returns the angle corresponding to the ellipse parameter.... 


Thanks for the explanation.  Even though I found a different way to get the start and end angles I wanted, without any big calculation, that certainly does answer the question of what the (assoc 41) value represents.  [I wonder what makes that the preferred way to store such information, but as they say, "why ask why?"]  I will definitely consider, as Rogerio wondered, whether that relationship might be of any use in working out a Through option for the routine, though I'm not very hopeful, since there are always at least two unknowns that play against each other.

Kent Cooper, AIA
Message 9 of 19


@rogerio_brazil wrote:

Kent, see an explanation of the association of the ellipse 41 at this link:

http://www.jefferypsanders.com/autolispexp_enti.html#Ellipse


Thanks for that link.  It doesn't really "explain" what it represents, but the fact that it identifies it as a Parameter value, rather than an angle [even though at the quadrant directions the Parameter is equal to the angle], is worth knowing.

Kent Cooper, AIA
Message 10 of 19
pbejse
in reply to: Kent1Cooper

Have you considered using entmake rather thatn the ellipse command? using mathematical approach of course.

Smiley Happy

 

Message 11 of 19
Kent1Cooper
in reply to: pbejse


@pbejse wrote:

Have you considered using entmake rather thatn the ellipse command? using mathematical approach of course. 


Yes, and it simplifies some things, but complicates others.

 

Assuming it's done by (subst) putting new values into a copy of the entity data list of the selected Ellipse, it spares the need to set the Layer or account for any color/linetype/etc. overrides.  And it potentially spares the need to align the UCS to the Ellipse [but see further below].

 

But it requires additional and in some cases hefty calculations that using the command doesn't, because the command takes care of them for you.  The new eccentricity (assoc 40) needs to be calculated and imposed, rather than just being a result of the new axis lengths.  The major-axis endpoint (assoc 11) needs to be calculated as a new 3D point list by sum-of-squares methods or something -- I don't think you can use (polar) or (angle) to help and have it work with the possibility of different Coordinate Systems.  And additional variables are probably required, because the new axis lengths can't just be calculated where used, but I think would need to be saved to use for calculating the new eccentricity and perhaps the parameters for elliptical arc ends.

 

For elliptical arcs, the starting and ending parameters add four complex calculations, to convert each from a parameter to an angle for the source Ellipse [see Message 3], and then using the new axis lengths and eccentricity of the new Ellipse, reverse that calculation to convert each back to a new parameter value to (subst) in.

 

But I suspect the toughest part might be determining whether to offset the Ellipse inboard or outboard based on a User-selected point.  That's easy enough if the selected Ellipse is in the current construction plane.  But if it's desirable to not align the UCS with the Ellipse, so as not to have to set it back, and the Ellipse is not in the current plane, and/or not perpendicular to the current view direction, a point that looks to the User like it's inside could well be outside, and the offset could occur in the wrong direction.  And if you're doing this when you're not even in the plan view of the current UCS, I think the opposite situation is also possible -- a point that looks to the User like it's outside could be inside.  There may be some way to interpret a projection in the current extrusion direction and determine whether it passes inside the Ellipse, but I suspect it would be more code-intensive than just aligning the UCS with it instead.

 

I would guess that for those who always work in the WCS, a version could be made that would be simpler/shorter, using (entmake).  But if you want it to work under possible differences between the current UCS and the current view direction and the plane of the Ellipse, the added complexities could well outweigh the savings.

Kent Cooper, AIA
Message 12 of 19
pbejse
in reply to: Kent1Cooper

Thank you for that, Good point Kent.

 

Now i will drop that idea and do something else. <ike work>

 

Smiley Happy

 

Message 13 of 19
t.willey
in reply to: Kent1Cooper

I think this will do what you want Kent.

 

(defun OffsetEllipse ( ename os / Data EndPt CenPt)
    
    (defun CreateEllipse ( cenPt endPt rat stParam endParam )
    
        (entmake
            (list
                (cons 0 "Ellipse")
                (cons 100 "AcDbEntity")
                (cons 100 "AcDbEllipse")
                (cons 10 cenPt)
                (cons 11 endPt)
                (cons 40 rat)
                (cons 41 stParam)
                (cons 42 endParam)
            )
        )
    )
    (setq Data (entget ename))
    (setq EndPt (mapcar (function +) (setq CenPt (cdr (assoc 10 Data))) (cdr (assoc 11 Data))))
    (setq EndPt (polar CenPt (angle CenPt EndPt) (+ os (distance CenPt EndPt))))
    (CreateEllipse CenPt (mapcar (function -) EndPt CenPt) (cdr (assoc 40 Data)) (cdr (assoc 41 Data)) (cdr (assoc 42 Data)))
)

Message 14 of 19
t.willey
in reply to: t.willey

Nope it doesn't do what you want.  I'll look into it a little more.  I guess I didn't understand what you wanted.

Message 15 of 19
Kent1Cooper
in reply to: t.willey


@t.willey wrote:

....

(defun OffsetEllipse ( ename os / Data EndPt CenPt)
    (defun CreateEllipse ( cenPt endPt rat stParam endParam )
        (entmake
            (list
                (cons 0 "Ellipse")
                (cons 100 "AcDbEntity")
                (cons 100 "AcDbEllipse")
                (cons 10 cenPt)
                (cons 11 endPt)
                (cons 40 rat)
                (cons 41 stParam)
                (cons 42 endParam)
            )
        )
    )
    (setq Data (entget ename))
    (setq EndPt (mapcar (function +) (setq CenPt (cdr (assoc 10 Data))) (cdr (assoc 11 Data))))
    (setq EndPt (polar CenPt (angle CenPt EndPt) (+ os (distance CenPt EndPt))))
    (CreateEllipse CenPt (mapcar (function -) EndPt CenPt) (cdr (assoc 40 Data)) (cdr (assoc 41 Data)) (cdr (assoc 42 Data)))
)


Thanks, and that's fine as far as how one can (entmake) an Ellipse, but I see several problems.

 

The 'os' variable would presumably be positive or negative, to offset outside or inside.   But determining which, from a User-selected which-side point, is a serious challenge if there are differences between the current view direction and/or the extrusion direction of the source Ellipse and/or the current Coordinate System.

 

Again, if there are directional/Coordinate System differences, the new EndPt result will be off, because (angle)'s return is always in terms of the current CS, while (polar)'s return is always relative to the X axis of the WCS.

 

Also in regard to different UCS possibilities, it doesn't match the new Ellipse's extrusion direction to the source, so even if it's the right shape and at the same center point, it could be tilted in a different plane.

 

The eccentricity of the new Ellipse will not be the same as that of the source, if its quadrant points are equidistant from those of the source, so just including the selected one's (assoc 40) value will give the wrong result, like scaling a copy of the source rather than offsetting it.  It would require calculating the source's minor half-axis length from the major half-axis and the eccentricity, adding/subtracting the offset distance from both, calculating the new eccentricity from those new lengths, and using that for the new 40 code.

 

Imposing the selected Ellipse's starting and ending parameter values (assoc 41/42) for an elliptical arc will result in starting and ending angles for the new one that differ from those of the source, except when one happens to be a quadrant direction.  Some may be satisfied with that, but I'm after matching the angles, not the parameters.

 

If the 'os' value is greater than the source's minor half-axis length and the offset direction is inward, the result would be a new Ellipse that's only the right distance from the source when measure through the center and across toward the other side.  That could even end up being outside the source Ellipse.

 

It would put the new Ellipse on the current Layer, not that of the source.

 

It doesn't account for Color/LType/LTScale/LWeight values other than default/Bylayer.  To get those most easily [and if it were valid to keep the source's eccentricity and start/end parameters], I would simply use (subst) to replace relevant parts of the Data list, take out the entity-name and handle entries, and (entmake) from that revised list.  That also gets other things correct, like the center and extrusion direction and layer, without needing to account for them.

 

To do it right using (subst) in the Data list would "only" require changing the 11 and 40 codes, plus 41 and 42 if it's not a full Ellipse.  The 40 conversion isn't too hard.  The 41/42 conversion would be pretty complex but probably doable.  I think the biggest challenge would be figuring out the new 11 code while accounting for Coordinate-System-difference possibilities.

Kent Cooper, AIA
Message 16 of 19
t.willey
in reply to: Kent1Cooper

Almost had it Kent, but I can't get my sub-function ' IsPointInside ' to report correctly all the time.  I'm off for the rest of the year, so I won't be working on it anymore, but if you or anyone else wants to see what I've done, I'll attach the lisp.

Message 17 of 19
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:

....[Then there's the much more complicated issue of getting it to have the "Through" option that regular Offset has.  My son the mathematician tells me calculating the axes from a point that might be anywhere would require solving a fourth-degree polynomial equation, which apparently can't be done with precision.  So it may involve approximating, testing the result, adjusting and approximating again, etc., until it's "close enough," to whatever precision is needed.  I'm thinking about that....]


Here it is, complete with a Through option, and various potential error situations accounted for.  It was really interesting to figure out the cause of certain (while) function endless-loop problems, but I think it's pretty fool-proof now.

Kent Cooper, AIA
Message 18 of 19
Kent1Cooper
in reply to: Kent1Cooper

[....but the word "Numerator" in one of the comments should be "Divisor" or "Denominator"....]

Kent Cooper, AIA
Message 19 of 19
Kent1Cooper
in reply to: Kent1Cooper

A small refinement:

 

The command makes a new Ellipse offset from a selected one.  Before, if the selected one had a color, linetype, linetype scale or lineweight that was not default/bylayer, it would match the new one to any such properties.  However, it only checked for those properties of the selected Ellipse.  If the new one had any of those non-default properties because of current-entity System Variable settings [CECOLOR, etc.], but the selected one did not, it would not make the new one match the selected one [that is, remove the non-default override], because it didn't look at those properties of the new one.

 

The attached takes care of that.  If either the selected Ellipse or the new one has non-default settings for any of those properties, it forces the new one to match the selected one.

Kent Cooper, AIA

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

Post to forums  

Autodesk Design & Make Report

”Boost