Sketcher: Ellipse support

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
abdullah
Posts: 3458
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Ellipse support

Postby abdullah » Thu Sep 18, 2014 6:09 pm

This approach of equal angles is what I am trying these day to put into a right mathematical form. You have equal angles with the normal and with the tangent....
jmaustpc
Posts: 9639
Joined: Tue Jul 26, 2011 6:28 am
Location: Australia

Re: Sketcher: Ellipse support

Postby jmaustpc » Thu Sep 18, 2014 6:24 pm

Hi all

This does a few interesting things. Firstly I think I have worked out how to constrain an ellipse with construction lines, "point on line", "perpendicular", "distance", "angle" constraints. If you use a line with point on line at either end on the ellipse, and then point on line with the centre of the ellipse, the line will still not definitely be restricted to the major axis as it can still rotate around the ellipse. The major and minor axis are the only place where a perpendicular line attached to the end of the axis line would also be tangent to the ellipse. So I made my minor axis line, perpendicular to the major axis and created a new line on one end of the major axis, perpendicular to the major axis and tangent to the ellipse. Now if I constrain the axis lines with "distance constraint" and set angle to one of them ...the ellipse is constrained. I added a symmetry and distance to my major axis perpendicular end line just so that the sketch would be fully constrained.


I also add something Werner said, if I am remembering what he said correctly, as a method to find the focus at each end. I think he said the hypotenuse of a right triangle of two equal sides from the minor axis would be the same length as centre to focus along the major axis. So I did that as well. I suspect I might have it wrong...but I will look into it later.

This is what it looks like.
ellipse_constrainedwithconstructionlines.jpg
ellipse_constrainedwithconstructionlines.jpg (24.95 KiB) Viewed 1223 times
and here is the FreeCAD file

Adjusting the angle constraint on the line on the major axis will rotate the ellipse...this works well for small movements of about 10 degrees at a time but some larger steps cause FreeCAD to have to think for a long time...some angles are invalid for some reason...it does not like 0 or 180 degrees. At first I tried to change from 120 to 40 degrees, FreeCAD said that 40 degrees was invalid after having thought about it for a long time...yet later when I moved it 10 degrees at a time FreeCAD had no problems going to 40 degrees.

Jim
abdullah
Posts: 3458
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Ellipse support

Postby abdullah » Thu Sep 18, 2014 6:42 pm

Jim, for the foci just make two lines of size major radius, coincident at the end of the minor radius, the other end point on line with the major axis (one to each side). Ulrich did it so in his first point on ellipse simulation...
jmaustpc
Posts: 9639
Joined: Tue Jul 26, 2011 6:28 am
Location: Australia

Re: Sketcher: Ellipse support

Postby jmaustpc » Thu Sep 18, 2014 6:50 pm

abdullah wrote:Jim, for the foci just make two lines of size major radius, coincident at the end of the minor radius, the other end point on line with the major axis (one to each side). Ulrich did it so in his first point on ellipse simulation...
AH! that's right ...that's what it was...I thought I might have that screwed up... :)

But I was please to work out a method of constraining the ellipse with the lines without the specific ellipse constraints....I thought that was interesting. :)

Jim
User avatar
DeepSOIC
Posts: 7600
Joined: Fri Aug 29, 2014 12:45 am
Location: Saint-Petersburg, Russia

Re: Sketcher: Ellipse support

Postby DeepSOIC » Thu Sep 18, 2014 8:13 pm

Here is an idea: mirror one of the focuses using the line to be constrained, and calculate the distance between the mirrored focus and the other (still real) focus! (This length) minus (sum of ellipse radii) is your error function! [(sum of ellipse radii) - the same stuff that is used as a point-on-ellipse constraint]
Attachments
ellipse tangent 2.FCStd
Proof of concept. Delete constraint "err=0" to unlock the line and see the error function in action.
(4.42 KiB) Downloaded 17 times
err_func.png
err_func.png (14.41 KiB) Viewed 1202 times
ulrich1a
Posts: 1922
Joined: Sun Jul 07, 2013 12:08 pm

Re: Sketcher: Ellipse support

Postby ulrich1a » Fri Sep 19, 2014 8:01 am

DeepSOIC wrote:Here is an idea: mirror one of the focuses using the line to be constrained, and calculate the distance between the mirrored focus and the other (still real) focus! (This length) minus (sum of ellipse radii) is your error function! [(sum of ellipse radii) - the same stuff that is used as a point-on-ellipse constraint]
This approach looks good. Variable names:
F1: Focus point 1
F2: Focus point 2
a: Major radius of ellipse
F1m: mirrored Focus point 1
P1: Point 1 of tangent line
P2: Point 2 of tangent line
The error function can then be expressed as:
err = sqrt((xF1m-xF2)^2 + (yF1m - yF2)^2) - 2*a

The mathematical task is then to express xF1m and yF1m in terms of: xF1, yF1, xP1, yP1, xP2 and yP2

I tried, but my vector calculation is not fluent enough to get it done in one evening.

Ulrich
User avatar
DeepSOIC
Posts: 7600
Joined: Fri Aug 29, 2014 12:45 am
Location: Saint-Petersburg, Russia

Re: Sketcher: Ellipse support

Postby DeepSOIC » Fri Sep 19, 2014 10:07 am

ulrich1a wrote:The mathematical task is then to express xF1m and yF1m in terms of: xF1, yF1, xP1, yP1, xP2 and yP2
I know how to do it. Here is the computation with all steps. You can substitute stuff to yield a single expression if you want.

Code: Select all

//calculate and normalize line direction vector
dx=xP2-xP1
dy=yP2-yP1
l=sqrt(dx^2+dy^2)
dx=dx/l
dy=dy/l
//the normal to the line
nx=dy
ny=-dx //minus! thanks Ulrich!
//calculate distance btw F1 and the line - the scalar product of the normal and a vector connecting P1 and F1:
dst=nx*(xF1-xP1)+ny*(yF1-yP1)// a signed value. sign is important and should be kept
//mirror the point by double dst along normal (backwards)
xF1m=xF1-2.0*dst*nx
yF1m=yF1-2.0*dst*ny
//done =) hope I didn't goof anything
 
hint: instead of "sqrt(smth) - 2*a" one can use "smth - (2*a)^2". This should work just as well (maybe even better, the function doesn't have infinite derivatives near zeros) and is a bit faster to compute.
Last edited by DeepSOIC on Fri Sep 19, 2014 12:48 pm, edited 1 time in total.
ulrich1a
Posts: 1922
Joined: Sun Jul 07, 2013 12:08 pm

Re: Sketcher: Ellipse support

Postby ulrich1a » Fri Sep 19, 2014 10:19 am

DeepSOIC wrote://the normal to the line
nx=dy
ny=dx
I think it should be either
nx=-dy
ny=dx
or
nx=dy
ny=-dx

Ulrich
abdullah
Posts: 3458
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Ellipse support

Postby abdullah » Fri Sep 19, 2014 12:27 pm

Ok. I have implemented it, but the result is not good, so most probably I made some calculation mistake. I leave here what I did in sage:

Code: Select all

{{{id=1|
from sympy import symbols
from sympy.utilities.codegen import codegen
a = var('a')
print "a is major axis of the ellipse"
b = var('b')
print "b is minor axis of the ellipse"
t = var('t')
print "t is an angle parameter for a point in the ellipse"
phip = var('phip')
print "phi is the angle of the major axis with the X-Axis"
X_c = var('X_c')
print "Xc is the x of the center point in the ellipse"
Y_c = var('Y_c')
print "Yc is the y of the center point in the ellipse"
X_0 = var('X_0')
print "X0 is the x of the point on the line that is the contact point"
Y_0 = var('Y_0')
print "Y0 is the y of the point on the line that is the contact point"
X_1 = var('X_1')
print "X1 is the x of the first point of the line"
Y_1 = var('Y_1')
print "Y1 is the y of the first point of the line"
X_2 = var('X_2')
print "X2 is the x of the second point of the line"
Y_2 = var('Y_2')
print "Y2 is the y of the second point of the line"
P=vector([X_0,Y_0])
print "P is the point on the line"
P1=vector([X_1,Y_1])
print "P1 is the first extreme point"
P2=vector([X_2,Y_2])
print "P2 is the first extreme point"
///
a is major axis of the ellipse
b is minor axis of the ellipse
t is an angle parameter for a point in the ellipse
phi is the angle of the major axis with the X-Axis
Xc is the x of the center point in the ellipse
Yc is the y of the center point in the ellipse
X0 is the x of the point on the line that is the contact point
Y0 is the y of the point on the line that is the contact point
X1 is the x of the first point of the line
Y1 is the y of the first point of the line
X2 is the x of the second point of the line
Y2 is the y of the second point of the line
P is the point on the line
P1 is the first extreme point
P2 is the first extreme point
}}}

{{{id=2|
dF=sqrt(a^2-b^2)
F1=vector([X_c,Y_c])+dF*vector([cos(phip), sin(phip)])
F2=vector([X_c,Y_c])-dF*vector([cos(phip), sin(phip)])
X_F1=F1[0]
Y_F1=F1[1]
X_F2=F2[0]
Y_F2=F2[1]
///
}}}

{{{id=3|
t_v=(P2-P1)/sqrt((P2-P1)*(P2-P1))
show(t_v)
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\left(-\frac{X_{1} - X_{2}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}},\,-\frac{Y_{1} - Y_{2}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}}\right)</script></html>
}}}

{{{id=4|
N=vector([t_v[1],-t_v[0]])
show(N)
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\left(-\frac{Y_{1} - Y_{2}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}},\,\frac{X_{1} - X_{2}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}}\right)</script></html>
}}}

{{{id=5|
d_lF1=N*(P1-F1)
show(d_lF1)
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}-\frac{{\left(\sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right) - Y_{1} + Y_{c}\right)} {\left(X_{1} - X_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} + \frac{{\left(\sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right) - X_{1} + X_{c}\right)} {\left(Y_{1} - Y_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}}</script></html>
}}}

{{{id=7|
print "this is the mirror of F1"
F1_m = F1 - 2*d_lF1*N
show(F1_m)
///
this is the mirror of F1
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\left(-\frac{2 \, {\left(\frac{{\left(\sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right) - Y_{1} + Y_{c}\right)} {\left(X_{1} - X_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} - \frac{{\left(\sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right) - X_{1} + X_{c}\right)} {\left(Y_{1} - Y_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}}\right)} {\left(Y_{1} - Y_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} + \sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right) + X_{c},\,\frac{2 \, {\left(\frac{{\left(\sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right) - Y_{1} + Y_{c}\right)} {\left(X_{1} - X_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} - \frac{{\left(\sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right) - X_{1} + X_{c}\right)} {\left(Y_{1} - Y_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}}\right)} {\left(X_{1} - X_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} + \sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right) + Y_{c}\right)</script></html>
}}}

{{{id=8|
DM = sqrt((F1_m-F2)*(F1_m-F2)) - 2*a
show(DM)
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}-2 \, a + \sqrt{4 \, {\left(\frac{{\left(\frac{{\left(\sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right) - Y_{1} + Y_{c}\right)} {\left(X_{1} - X_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} - \frac{{\left(\sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right) - X_{1} + X_{c}\right)} {\left(Y_{1} - Y_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}}\right)} {\left(X_{1} - X_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} + \sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right)\right)}^{2} + 4 \, {\left(\frac{{\left(\frac{{\left(\sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right) - Y_{1} + Y_{c}\right)} {\left(X_{1} - X_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} - \frac{{\left(\sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right) - X_{1} + X_{c}\right)} {\left(Y_{1} - Y_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}}\right)} {\left(Y_{1} - Y_{2}\right)}}{\sqrt{{\left(X_{1} - X_{2}\right)}^{2} + {\left(Y_{1} - Y_{2}\right)}^{2}}} - \sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right)\right)}^{2}}</script></html>
}}}
I am going to check it anyway now (I just blind-coded it). I put the missing sign in the normal as Ulrich says...
But I was please to work out a method of constraining the ellipse with the lines without the specific ellipse constraints....I thought that was interesting. :)
Hey Jim! I think it is indeed interesting to try this things out, because if want to get rid of specific constraints, then this has to work well...
abdullah
Posts: 3458
Joined: Sun May 04, 2014 3:16 pm

Re: Sketcher: Ellipse support

Postby abdullah » Fri Sep 19, 2014 12:32 pm

Adjusting the angle constraint on the line on the major axis will rotate the ellipse...this works well for small movements of about 10 degrees at a time but some larger steps cause FreeCAD to have to think for a long time...some angles are invalid for some reason...it does not like 0 or 180 degrees. At first I tried to change from 120 to 40 degrees, FreeCAD said that 40 degrees was invalid after having thought about it for a long time...yet later when I moved it 10 degrees at a time FreeCAD had no problems going to 40 degrees.
Only opening that sketch takes a long while, like a minute and a half... :o :shock: we have so much to improve...