## Sketcher: Ellipse support

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
ulrich1a
Posts: 1958
Joined: Sun Jul 07, 2013 12:08 pm

### Re: Sketcher: Ellipse support

abdullah wrote:If you want to take a look, this is the (math) work behind the "still-not-properly-working" Point on Ellipse:

http://www.sagenb.org/home/pub/5049
Unfortunately your notebook is not available for the public.
abdullah wrote:I see what you have done, but I think it can not be done like this (or I do not see how).
The error function is: err=sqrt((yF2−yp)^2+(xF2−xp)^2)+sqrt((yF1−yp)^2+(xF1−xp)^2)−2*a

I made a contour plot of err(xp,yp). I just choosed some simple parameters like xF1 = -1; xF2 = 1, yF1=yF2=0, a = 2. This function is zero at all points on the ellipse, negative inside of the ellipse and positive outside of the ellipse. So this function should be well suited for the point on ellipse constraint.
Attached is also the revised wxMaxima notebook with the contour_plot command. (Saves plot as png-image)

Ulrich
Attachments
Ellipse_Focus_point_equation_rev1.wxm.zip
revised maxima notebook with contour_plot
contour plot of the error function for point on ellipse
error_function_point_on_ellipse.png (5.31 KiB) Viewed 1198 times
abdullah
Posts: 3868
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Ellipse support

Unfortunately your notebook is not available for the public.
I usually use sage on my PC. I used that public server just to be able to share it with the FreeCAD community. It seems like they had disabled all public sheets, as someone was using them to attack computers via Javascript...

With own computer:

If you want, in Ubuntu is a PPA:

Code: Select all

apt-add-repository -y ppa:aims/sagemath
apt-get update
apt-get install sagemath-upstream-binary
after install you can type sage in the terminal. In the sage prompt you type notebook() and it will open your browser with a localhost url.

Using http://www.sagenb.org/

In any of the approaches: create a new sheet. Click the "edit buttom" and paste this:
{{{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 from which we want to calculate the distance to the ellipse"
Y_0 = var('Y_0')
print "Y0 is the y of the point from which we want to calculate the distance to the ellipse"
P=vector([X_0,Y_0])
print "P is the point"
Xt=X_c+a*cos(t)*cos(phip)-b*sin(t)*sin(phip)
print "Xt is the x coordinate of a point in the ellipse"
Yt=Y_c+a*cos(t)*sin(phip)+b*sin(t)*cos(phip)
print "Yt is the y coordinate of a point in the ellipse"
E=vector([Xt,Yt])
print "E is the points of the ellipse"
///
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 from which we want to calculate the distance to the ellipse
Y0 is the y of the point from which we want to calculate the distance to the ellipse
P is the point
Xt is the x coordinate of a point in the ellipse
Yt is the y coordinate of a point in the ellipse
E is the points of the ellipse
}}}

{{{id=2|
dXtdt= Xt.derivative(t)
dYtdt= Yt.derivative(t)
dEdt=E.derivative(t)
///
}}}

{{{id=3|
print "This equation means the distance from point to the point closest in the ellipse must be perpendicular to the tangent to the Ellipse at that point"
thetafunc=((P-E)*dEdt).expand().simplify_trig()
show(thetafunc)
simplif=thetafunc.substitute(phi=0,X_c=0,Y_c=0)
show(simplif)
print "thetafunc is the equation that must be zero, giving the t of the point of the ellipse being the closest to P"
thetafuncs=thetafunc._sympy_()
show(thetafuncs)
[(c_name, c_code), (h_name, c_header)] = codegen(("thetafunc", thetafuncs), "C", "test")
print c_code
///
This equation means the distance from point to the point closest in the ellipse must be perpendicular to the tangent to the Ellipse at that point
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}{\left(a^{2} - b^{2}\right)} \cos\left(t\right) \sin\left(t\right) - {\left(b \cos\left(t\right) \sin\left(\mbox{phip}\right) + a \cos\left(\mbox{phip}\right) \sin\left(t\right)\right)} X_{0} + {\left(b \cos\left(t\right) \sin\left(\mbox{phip}\right) + a \cos\left(\mbox{phip}\right) \sin\left(t\right)\right)} X_{c} + {\left(b \cos\left(\mbox{phip}\right) \cos\left(t\right) - a \sin\left(\mbox{phip}\right) \sin\left(t\right)\right)} Y_{0} - {\left(b \cos\left(\mbox{phip}\right) \cos\left(t\right) - a \sin\left(\mbox{phip}\right) \sin\left(t\right)\right)} Y_{c}</script></html>
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}{\left(a^{2} - b^{2}\right)} \cos\left(t\right) \sin\left(t\right) - {\left(b \cos\left(t\right) \sin\left(\mbox{phip}\right) + a \cos\left(\mbox{phip}\right) \sin\left(t\right)\right)} X_{0} + {\left(b \cos\left(\mbox{phip}\right) \cos\left(t\right) - a \sin\left(\mbox{phip}\right) \sin\left(t\right)\right)} Y_{0}</script></html>
thetafunc is the equation that must be zero, giving the t of the point of the ellipse being the closest to P
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|-X_0*(a*sin(t)*cos(phip)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(phip)*cos(t))|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c*(a*sin(t)*cos(phip)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(phip)*cos(t))|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_0*(-a*sin(phip)*sin(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*cos(phip)*cos(t))|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c*(-a*sin(phip)*sin(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*cos(phip)*cos(t))|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(t)*cos(t)|</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double thetafunc(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return -X_0*(a*sin(t)*cos(phip) + b*sin(phip)*cos(t)) + X_c*(a*sin(t)*cos(phip) + b*sin(phip)*cos(t)) + Y_0*(-a*sin(phip)*sin(t) + b*cos(phip)*cos(t)) - Y_c*(-a*sin(phip)*sin(t) + b*cos(phip)*cos(t)) + (pow(a, 2) - pow(b, 2))*sin(t)*cos(t);

}
}}}

{{{id=4|
print "dtheta is the first derivative of thetafunc above, used to solve for t using Newton-Raphson"
dtheta=thetafunc.derivative(t).simplify_trig()
dthetas=dtheta._sympy_()
show(dtheta)
[(c_name, c_code), (h_name, c_header)] = codegen(("dtheta", dthetas), "C", "test")
print c_code
///
dtheta is the first derivative of thetafunc above, used to solve for t using Newton-Raphson
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}2 \, {\left(a^{2} - b^{2}\right)} \cos\left(t\right)^{2} - {\left(a \cos\left(\mbox{phip}\right) \cos\left(t\right) - b \sin\left(\mbox{phip}\right) \sin\left(t\right)\right)} X_{0} + {\left(a \cos\left(\mbox{phip}\right) \cos\left(t\right) - b \sin\left(\mbox{phip}\right) \sin\left(t\right)\right)} X_{c} - {\left(a \cos\left(t\right) \sin\left(\mbox{phip}\right) + b \cos\left(\mbox{phip}\right) \sin\left(t\right)\right)} Y_{0} + {\left(a \cos\left(t\right) \sin\left(\mbox{phip}\right) + b \cos\left(\mbox{phip}\right) \sin\left(t\right)\right)} Y_{c} - a^{2} + b^{2}</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double dtheta(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return -X_0*(a*cos(phip)*cos(t) - b*sin(phip)*sin(t)) + X_c*(a*cos(phip)*cos(t) - b*sin(phip)*sin(t)) - Y_0*(a*sin(phip)*cos(t) + b*sin(t)*cos(phip)) + Y_c*(a*sin(phip)*cos(t) + b*sin(t)*cos(phip)) - pow(a, 2) + pow(b, 2) + 2*(pow(a, 2) - pow(b, 2))*pow(cos(t), 2);

}
}}}

{{{id=5|
print "DM is the modulus of the distance from point P to the point in the ellipse E"
D=P-E
DM=sqrt(D*D)
show(DM)
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\sqrt{{\left(a \cos\left(\mbox{phip}\right) \cos\left(t\right) - b \sin\left(\mbox{phip}\right) \sin\left(t\right) - X_{0} + X_{c}\right)}^{2} + {\left(a \cos\left(t\right) \sin\left(\mbox{phip}\right) + b \cos\left(\mbox{phip}\right) \sin\left(t\right) - Y_{0} + Y_{c}\right)}^{2}}</script></html>
}}}

{{{id=6|
print "Those are the simplified partials assuming that t does not vary with them"
DM_X0=DM.derivative(X_0)
DM_Y0=DM.derivative(Y_0)
DM_Xc=DM.derivative(X_c)
DM_Yc=DM.derivative(Y_c)
DM_a=DM.derivative(a)
DM_b=DM.derivative(b)
DM_phi=DM.derivative(phip)
///
Those are the simplified partials assuming that t does not vary with them
}}}

{{{id=87|
DM_X0s=DM_X0._sympy_()
show(DM_X0s)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_X0", DM_X0s), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|-(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))/((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))**2)**(1/2)|</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_X0(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return -(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t))/sqrt(pow(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t), 2) + pow(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip), 2));

}
}}}

{{{id=88|
DM_Y0s=DM_Y0._sympy_()
show(DM_Y0s)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_Y0", DM_Y0s), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|-(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))/((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))**2)**(1/2)|</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_Y0(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return -(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip))/sqrt(pow(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t), 2) + pow(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip), 2));

}
}}}

{{{id=89|
DM_Xcs=DM_Xc._sympy_()
show(DM_Xcs)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_Xc", DM_Xcs), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))/((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))**2)**(1/2)|</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_Xc(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return (-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t))/sqrt(pow(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t), 2) + pow(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip), 2));

}
}}}

{{{id=90|
DM_Ycs=DM_Yc._sympy_()
show(DM_Ycs)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_Yc", DM_Ycs), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))/((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))**2)**(1/2)|</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_Yc(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return (-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip))/sqrt(pow(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t), 2) + pow(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip), 2));

}
}}}

{{{id=91|
DM_as=DM_a._sympy_()
show(DM_as)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_a", DM_as), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))*sin(phip)*cos(t))/((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))**2)**(1/2)|</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_a(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return ((-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t))*cos(phip)*cos(t) + (-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip))*sin(phip)*cos(t))/sqrt(pow(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t), 2) + pow(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip), 2));

}
}}}

{{{id=92|
DM_bs=DM_b._sympy_()
show(DM_bs)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_b", DM_bs), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|(-(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))*sin(phip)*sin(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))*sin(t)*cos(phip))/((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))**2)**(1/2)|</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_b(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return (-(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t))*sin(phip)*sin(t) + (-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip))*sin(t)*cos(phip))/sqrt(pow(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t), 2) + pow(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip), 2));

}
}}}

{{{id=93|
DM_phis=DM_phi._sympy_()
show(DM_phis)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_phi", DM_phis), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|(-(a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))*(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))*(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip)))/((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*cos(phip)*cos(t)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b*sin(phip)*sin(t))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*sin(phip)*cos(t)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*sin(t)*cos(phip))**2)**(1/2)|</script></html>
/******************************************************************************
* Code generated with sympy 0.7.1 *
* *
* *
* This file is part of 'project' *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_phi(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip, double t) {

return (-(a*sin(phip)*cos(t) + b*sin(t)*cos(phip))*(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t)) + (a*cos(phip)*cos(t) - b*sin(phip)*sin(t))*(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip)))/sqrt(pow(-X_0 + X_c + a*cos(phip)*cos(t) - b*sin(phip)*sin(t), 2) + pow(-Y_0 + Y_c + a*sin(phip)*cos(t) + b*sin(t)*cos(phip), 2));

}
}}}

{{{id=126|

///
}}}
I am going to give a shot to your function...
abdullah
Posts: 3868
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Ellipse support

Congrats Ulrich!!

Your minimization function seems to work well (Jim will probably try to find were it does not soon ).

You can find it here:
https://github.com/abdullahtahiriyo/Fre ... master.git
* [new branch] sketcher_elipse -> sketcher_elipse

I have used your idea. Extended to the case of an ellipse not centered and tilted, and based on that calculated the partials. THis is it:

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 from which we want to calculate the distance to the ellipse"
Y_0 = var('Y_0')
print "Y0 is the y of the point from which we want to calculate the distance to the ellipse"
P=vector([X_0,Y_0])
print "P is the 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 from which we want to calculate the distance to the ellipse
Y0 is the y of the point from which we want to calculate the distance to the ellipse
P is the 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]
DM=sqrt((Y_F2-Y_0)^2+(X_F2-X_0)^2)+sqrt((Y_F1-Y_0)^2+(X_F1-X_0)^2)-2*a
///
}}}

{{{id=3|
show(DM)
DMs=DM._sympy_()
show(DMs)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM", DMs), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}-2 \, a + \sqrt{{\left(\sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right) + X_{0} - X_{c}\right)}^{2} + {\left(\sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right) + Y_{0} - Y_{c}\right)}^{2}} + \sqrt{{\left(\sqrt{a^{2} - b^{2}} \cos\left(\mbox{phip}\right) - X_{0} + X_{c}\right)}^{2} + {\left(\sqrt{a^{2} - b^{2}} \sin\left(\mbox{phip}\right) - Y_{0} + Y_{c}\right)}^{2}}</script></html>
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|-2*a|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt((X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|</script></html>
/******************************************************************************
*                      Code generated with sympy 0.7.4                       *
*                                                                            *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip) {

return -2*a + sqrt(pow(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) + sqrt(pow(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2));

}
}}}

{{{id=4|
DM_X0=DM.derivative(X_0)
DM_Y0=DM.derivative(Y_0)
DM_Xc=DM.derivative(X_c)
DM_Yc=DM.derivative(Y_c)
DM_a=DM.derivative(a)
DM_b=DM.derivative(b)
DM_phi=DM.derivative(phip)
///
}}}

{{{id=5|
DM_X0s=DM_X0._sympy_()
show(DM_X0s)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_X0", DM_X0s), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|(X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))/sqrt((X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))/sqrt((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|</script></html>
/******************************************************************************
*                      Code generated with sympy 0.7.4                       *
*                                                                            *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_X0(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip) {

return (X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))/sqrt(pow(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) - (-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))/sqrt(pow(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2));

}
}}}

{{{id=6|
DM_Y0s=DM_Y0._sympy_()
show(DM_Y0s)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_Y0", DM_Y0s), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))/sqrt((X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))/sqrt((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|</script></html>
/******************************************************************************
*                      Code generated with sympy 0.7.4                       *
*                                                                            *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_Y0(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip) {

return (Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))/sqrt(pow(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) - (-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))/sqrt(pow(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2));

}
}}}

{{{id=7|
DM_Xcs=DM_Xc._sympy_()
show(DM_Xcs)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_Xc", DM_Xcs), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|-(X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))/sqrt((X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))/sqrt((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|</script></html>
/******************************************************************************
*                      Code generated with sympy 0.7.4                       *
*                                                                            *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_Xc(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip) {

return -(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))/sqrt(pow(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) + (-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))/sqrt(pow(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2));

}
}}}

{{{id=8|
DM_Ycs=DM_Yc._sympy_()
show(DM_Ycs)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_Yc", DM_Ycs), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|-(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))/sqrt((X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))/sqrt((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|</script></html>
/******************************************************************************
*                      Code generated with sympy 0.7.4                       *
*                                                                            *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_Yc(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip) {

return -(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))/sqrt(pow(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) + (-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))/sqrt(pow(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2));

}
}}}

{{{id=9|
DM_as=DM_a._sympy_()
show(DM_as)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_a", DM_as), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|(a*(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))*cos(phip)/sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))*sin(phip)/sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2))/sqrt((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(a*(X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))*cos(phip)/sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|a*(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))*sin(phip)/sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2))/sqrt((X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|2|</script></html>
/******************************************************************************
*                      Code generated with sympy 0.7.4                       *
*                                                                            *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_a(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip) {

return (a*(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))*cos(phip)/sqrt(pow(a, 2) - pow(b, 2)) + a*(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))*sin(phip)/sqrt(pow(a, 2) - pow(b, 2)))/sqrt(pow(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) + (a*(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))*cos(phip)/sqrt(pow(a, 2) - pow(b, 2)) + a*(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))*sin(phip)/sqrt(pow(a, 2) - pow(b, 2)))/sqrt(pow(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) - 2;

}
}}}

{{{id=10|
DM_bs=DM_b._sympy_()
show(DM_bs)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_b", DM_bs), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|-(b*(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))*cos(phip)/sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))*sin(phip)/sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2))/sqrt((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|(b*(X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))*cos(phip)/sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|b*(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))*sin(phip)/sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2))/sqrt((X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|</script></html>
/******************************************************************************
*                      Code generated with sympy 0.7.4                       *
*                                                                            *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_b(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip) {

return -(b*(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))*cos(phip)/sqrt(pow(a, 2) - pow(b, 2)) + b*(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))*sin(phip)/sqrt(pow(a, 2) - pow(b, 2)))/sqrt(pow(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) - (b*(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))*cos(phip)/sqrt(pow(a, 2) - pow(b, 2)) + b*(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))*sin(phip)/sqrt(pow(a, 2) - pow(b, 2)))/sqrt(pow(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2));

}
}}}

{{{id=11|
DM_phis=DM_phi._sympy_()
show(DM_phis)
[(c_name, c_code), (h_name, c_header)] = codegen(("DM_phi", DM_phis), "C", "test")
print c_code
///
<html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\verb|(-sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*(-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))*sin(phip)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))*cos(phip))/sqrt((-X_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-Y_0|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(-sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*(X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))*sin(phip)|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))*cos(phip))/sqrt((X_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|X_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*cos(phip))**2|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|(Y_0|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|Y_c|\phantom{\verb!x!}\verb|+|\phantom{\verb!x!}\verb|sqrt(a**2|\phantom{\verb!x!}\verb|-|\phantom{\verb!x!}\verb|b**2)*sin(phip))**2)|</script></html>
/******************************************************************************
*                      Code generated with sympy 0.7.4                       *
*                                                                            *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double DM_phi(double X_0, double X_c, double Y_0, double Y_c, double a, double b, double phip) {

return (-sqrt(pow(a, 2) - pow(b, 2))*(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))*sin(phip) + sqrt(pow(a, 2) - pow(b, 2))*(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))*cos(phip))/sqrt(pow(-X_0 + X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(-Y_0 + Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2)) + (-sqrt(pow(a, 2) - pow(b, 2))*(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip))*sin(phip) + sqrt(pow(a, 2) - pow(b, 2))*(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip))*cos(phip))/sqrt(pow(X_0 - X_c + sqrt(pow(a, 2) - pow(b, 2))*cos(phip), 2) + pow(Y_0 - Y_c + sqrt(pow(a, 2) - pow(b, 2))*sin(phip), 2));

}
}}}

{{{id=12|

///
}}}
Edit: I was so obsessed trying to make it converge to the closest point in the ellipse, that even if I would consider a based on focus approach, I would never have seen it without trying to force it to converge there. I feel a little bit stupid and a happy that this finally worked out.
abdullah
Posts: 3868
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Ellipse support

Hey Jim!!

As you see the new partials seem to pass the Jim-redundacy test:
Ellipse18.png (97.19 KiB) Viewed 1172 times
Now you will have to try harder to break it... I dare you
abdullah
Posts: 3868
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Ellipse support

Ok while Jim tries to disturb our circles (or more appropriate to this case our ellipse)... we can move on to the tangent case...
... we need a function that would move the points of a line (P1,P2) so that it is tangent to the ellipse...

My current approach (which jumps like crazy, and has redundancy problems) is:
// 1. Starting from the parametric equations, solve for t that has the same tangent slope as the line
// E'(t)=m => two roots t0, t1
// 2. Calculate distance from E(t0) and E(t1) to line => select the one (ts) shortest distance to line
// (this is implicit selection by choosing an appropriate initial guess for Newton-Raphson)
// 3. Calculate the partials of this distance assuming constant t of value ts.

I am giving awards to the best idea that converges. Ulrich got the PointOnEllipse constraint award and now it is named after him (the socalled Ulrich-partials)...who wants to be next??
wmayer
Posts: 16855
Joined: Thu Feb 19, 2009 10:32 am

### Re: Sketcher: Ellipse support

I am giving awards to the best idea that converges. Ulrich got the PointOnEllipse constraint award and now it is named after him (the socalled Ulrich-partials)...who wants to be next??
I have a question: do we only need a function that tells us that a point is inside, outside or on an ellipse or do we need the geometric smallest distance for this?
abdullah
Posts: 3868
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Ellipse support

PointOnEllipse is taken (by Ulrich), unless Jim comes with convergence problems (but I do not expect them because the matrix is very very very well conditioned compared to what I was getting using my method).

The current contest is for a line tangent to an ellipse.

The search is for a function of the 5 ellipse parameters (or anything you can derive from them, like the focuses) + 4 extra parameters (the coordinates of the extremes of the line, X_P1, Y_P1, X_P2, Y_P2) that when minimized, the line formed by P1 and P2 is tangent to the ellipse.

The function does not need to care or know if P1 and/or P2 is inside or outside the ellipse. The function does not need to converge to the geometric smallest distance. However, obviously the equation shall not put extra constraints on the elements other than being tangent.

In other words, the closest distance from an ellipse to a line is the distance between that line and the point of the ellipse, in which the tangent to the ellipse has the same slope as the line. It does not need to calculate this. It is good enough if it converges and does not set extra constraints...

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

### Re: Sketcher: Ellipse support

ahhh... I forgot, you can assume an ellipse aligned with the X axis and with center in 0,0. I can translate and rotate the equations myself afterwards...

Also see as an example the simplificity of Ulrich's equation compared to mine.

err=sqrt((yF2−yp)^2+(xF2−xp)^2)+sqrt((yF1−yp)^2+(xF1−xp)^2)−2*a

He actually only cares about a distance measurement of the error when the point is not on the ellipse; as opposed to my method that calculates the closest point of the ellipse and then the distance from this point of the ellipse to that point...
jmaustpc
Posts: 10525
Joined: Tue Jul 26, 2011 6:28 am
Location: Australia

### Re: Sketcher: Ellipse support

Hi Abdullah

I git pulled and it stuffed up my repo so I deleted everything and git cloned and re built FreeCAD all from scratch.

Now I get an error when I try to draw an ellipse in sketcher.

Unhandled exception in ViewProvider::eventCallback: Unsupported geometry type: Part::GeomEllipse
ellipsefailed.jpg (84.12 KiB) Viewed 1136 times
OS: Kubuntu 14.04.1 LTS
Word size of OS: 64-bit
Version: 0.15.4017 (Git)
Branch: sketcher_elipse
Hash: 7d71eaf08b3e671c4891b337f63e91f67aa0541e
Python version: 2.7.6
Qt version: 4.8.6
Coin version: 4.0.0a
SoQt version: 1.6.0a
OCC version: 6.7.1 oce compile from their master
abdullah
Posts: 3868
Joined: Sun May 04, 2014 3:16 pm

### Re: Sketcher: Ellipse support

If someone still has a working copy of the previous elipse brach please save it. I think I have done a newbie mistake with git+I failed to listen to the signs that I was doing it and I might have lost some work. Tomorrow I will evaluate the damage...sorry guys!!!

Edit: If someone has it and can put it in his own github and give me the link it might help me tomorrow...