MINISTRY OF EDUCATION AND SCIENCE OF THE RUSSIAN FEDERATION
State autonomous educational institution of higher education
«Lobachevsky State University of Nizhni Novgorod»
Faculty for International Students
Major (field) 02.04.01 « Mathematics and computer sciences»
Master’s degree thesis
topic:
«Function approximation using Bezier curves»
Prepared by: student of group MCs2
________________ Zarir Yassine
Signature
Supervised by:
Professor
________________ Marina Markina
Signature
Nizhni Novgorod
2017
2017
Table of Contents
3
3
Introduction to Bézier curves 4
Mathematical definition of Bezier curve 7
Finding extremities: root finding 8
Cardano’s method 9
Program realization I 11
Related topics 13
Least Squares Method 14
Mathematical definition of Least Squares 15
Lagrange polynomial 16
Program realization II 17
B-splines: 19
Back to our main topic : 21
Problem statement 26
Program realization III 27
Numerical results 28
Conclusion 30
References 31
Appendix 32
Introduction to Bézier curves
Bézier curves were named after Dr. Pierre Bézier. Bézier was a French engineer with the Renault car company, he developed and invented Bézier curve, a formulation of a cruve which would lend itself to shape design.
We consider it more understandable, to think of Bézier curves in terms of the center of mass of a some set of point masses. For instance, let us consider the following four masses located at points respectively.
We know that the center of mass of these four given point masses is defined by the following equation:
Let’s imagine, that we have each mass varies, so instead of being fixed, constant values, each of the masses is variying as a function of some parameter t.
More specific, let
The values of these masses as a function of t is shown in the following graph:
We see that for each value of t, the masses has different a different weight and the center of the masses is changing continuously. In other words, as t varies between 0 and 1, a curve is swept out by the center of masses.
This curve in Figure 2, is a cubic Bézier curve – cubic because the mass equations are cubic polynomials in t.
We clearly see that for any value of t,, and so we can simply write the equation of this Bézier curve as.
We note that when t = 0, thenand this makes the curve pass through . And also when t = 1, then, thus the curve also passes through point . The curve is tangent toand .
These variable massesare usually called blending functions and their locationsare called control points or Bézier points, the blending functions, in the case of Bézier curves, these blending functions are known as Bernstein polynomials.
Here some examples of Bézier curves of various degree:
A degreeBézier curve hascontrol points whose blending functions are denoted
Where :
We recall thatis called a binomial coefficient, and it is equal to.
In our first introductory example we had :
n = 3 and
By the way,is also referred to as the ith Bernstein polynomial of degree n.
Mathematical definition of Bezier curve
The equation of Bézier curve is defined as following:
Hereas mentioned before, are the Bernstein polynomials or Bernstein basis functions of degree n defined by :
Here we give some of the main properties of Bezier curve :
The curve begins atand ends at, we call this the endpoint interpolation property.
The curve is a straight line when all the control points are collinear.
The start (end) of the curve is tangent to the first (last) section of the Bézier polygon.
A curve can be split at any point into two sub-curves, or into arbitrarily many sub-curves, each of which is also a Bezier curve.
There is no local control in degree n Bezier curves, which means that any change to a control point implies a recalculation, which affects the aspect of the entire curve.
Finding extremities: root finding
Now that we have introduced the Bezier curves mathematically, let’s find the extremities of a Bezier curve by using the component functions and finding on them the maxima and minima;
we do that by solving and .
Linear derivatives:
it is trivial, finding the solution for “where does the line intersect with x-axis”:
The quadratic formula:
We know that the derivative of a cubic curve is a quadratic curve, and to find the roots of a quadratic Bezier implies that we can apply the Quadratic formula, so we have something that looks like the following:
Given
So, if it is possible for us to express a Bezier component function as a polynomial, we are almost done: by just plugging in the values into our quadratic formula, and we just compute the two values, we may turn our cubic Bézier into a quadratic one;
,And then:
,
and , So we can easily find the roots by using :
,, and
Cardano’s method
To find the points of a Bezier curve, we will use Cardano’s formula, which allows us to find the roots of the cubic equation : (1) , so the Cardano’s method provides us a simple technique for solving such equation.
To Solve (1), it is more convenient if we do the following substitution :
We let : (2), next step is that we replace (1) by a simpler equation : (3) where y is an unknown and p and q are some constant coefficients.
For any numbers u and v, they satisfy the binomial formula:
we have the following :(4).
Next step is to find a solution y to the equation (3) in the form : (5) knowing that we have managed to choose complex u and v such that : (6) and also :
(7) the pair u and v that satisfy (6) and (7) will also be satisfying the following: (8) .
So by the equation (7) their cubes u^3 and v^3 will be the two roots of the quadratic equation: (9) . with solutions : let Q =
In order to find u and v, we have now to find the cube roots of these solutions. In the case of we have complex roots.
We get the formula for finding the roots of the canonical form of the cubic equation:
,where andCalculating the value of the Bezier curve at a given point:
So we give an example on how to find the value of the function at any given point of the Bezier curve, the procedure is simple, we get the input from the user (the control points)
we do calculate the coefficients for the polynomial :where :
, , and
we find t and then we calculate .
For this purpose we created a program in Java that simulates this procedure, here is a snapshot of the program :
Next, we will be implementing a Java application that simulates the Bezier curve.
Program realization I
BezierCurve Application :
We have used the following technologies:
Integrated development environment (IDE) : NetBeans 8.0.2
Programming language : Java
Libraries/Frameworks: Built-in Java classes only. JDK 1.7
Compiled and executed on : Linux Machine (Ubuntu).
We have used Java as a programming language, due to the fact that most of our work is done one a Linux machine. And for a better performance and multi-platform approach, we think that Java is the best choice.
Advantages over C and C++:
It is a compiled to an intermediate language called the byte code, which is independent of the machine::
We have an automatic garbage collector.
Pointers are not needed anymore.
We don’t have to think about header files “.h”.
Definition of classes and their attributes and methods can be implemented in any order.
The Synchronization is built into the Java language.
Threading is also built into the language
We are provided with more debugging information that are into the binaries, making bugs easier to debug
We have something called late linking which the development more flexible..
The program’s aim is to draw a Bezier curve, the user gives as an input, locations, which are points, and when the user clicks on the draw button, the program draws a Bezier curve of the given inputs points.
Here is a snapshot of the program we made :
Related topics
The need for finding an approximating function often arises in many real world problems, in
econometric, in numerical problems and many other fields, In few words; One is provided a finite set of data points and would to determine a functional form.
For instance, let’s suppose we know that the period’s value of the interest rate at some moment, is let’s say some function of the current interest rate, but we have no idea about the function form. We have the following relationship:
And the question is then whether with relatively enough data we can find the function form of f. The need for an approximating functional form may also arises even if we could find in principle the function value for any given set of inputs but It may be very expensive to do so. For instance, the function value can be an outcome of many complex calculations and it can take a lot of computing time to calculate one function value, where we can use an approximation function form and we could obtain some approximate function values much quicker, it happens that a formula for some given function is known, but too complex to evaluate efficiently as we explained before, so a few known data points from the original function can be used, and we create an interpolation based on a simpler function. So the general idea is to come up with an approximating functional form using finite set of data points. This problem is pretty close to interpolation, which is method of constructing new data using know data, We have introduced before the Bezier curves which we may use in our investigation, but we may also discuss and use other techniques and methods, such like: least squares method, linear interpolation, polynomial interpolation (Lagrange Method), we will also discuss multivariate interpolation, methods include bi-linear and cubic interpolations in two dimensions, we will discuss also the real world applications of these method
Least Squares Method
In simple words, the method of least squares is a procedure that allow us to determine the best fit line to data, Least squares method is considered to be a standard approach in regression analysis to the approximate solution of some over-determined systems, Least squares is called so, because the overall solution minimizes the sum of squares of the errors made in the results of each single equation. Often in the real world, we expect to find some linear relationships between variables. For example, the force of a given spring linearly depends on the displacement of the spring, so we have the following relationship : (where y is the force and x is the displacement of the spring, and k is the spring constant). To check this possible relationship, researchers may study it in tthe lab and make measures what the force is for difference displacements based on different experiments, so they collect and assemble data of the form for ; here the is the observed force in Newtons when we displace the spring by meters.
Mathematical definition of Least Squares
Given data , we can define the error associated to by :
This is simply N times the variance of the data set . There is no difference whether or not we investigate the variance or N times the variance to be our error, and we not that the error is a function of two variables.
The aim is to find some values a and b that minimize this error. We know that in multivariable calculus, it requires us to find the values of (a, b) for which:
Differentiating E(a, b) yields :
Simplifying:
We may express these equations as:
We have found that the value a and that minimizes the error is satisfying the matrix equation.
Lagrange polynomial
Lagrange polynomials are used in polynomial interpolation, they are used to construct a polynomial that passes through or interpolate k+1 data points:
where no two are the same, and the interpolating polynomial in the Lagrange form is a linear combination:
And Lagrange basis polynomials:
where 0 <= j <= k. We note that with the given initial assumption that no two are the same, so . so this expression is always well-defined.
This figure demonstrate a polynomial interpolation (Lagrange method) :
Program realization II
Approximation Tool Application:
We have used the following technologies:
Integrated development environment (IDE) : NetBeans 8.2
Programming language: Java
Libraries/Frameworks: Built-in Java classes only. JDK 1.8 and JavaFx
Compiled and executed on : Windows Machine (Windows 10).
We have used Java as a programming language, due to the fact that most of our work is done one a Linux machine. And for a better performance and multi-platform approach, we think that Java is the best choice. Here is a screen-shot our program :
Here is a screen-shot of our program, it illustrates least squares method.
And here we use our program to interpolate using Lagrange method:
B-splines:
Let’s start by a simple introduction about splines and what are they; Splines are just piecewise polynomial curves that are differentiable up to a given order, a very simple example that we can give is a piecewise linear spline, i.e, a polygonal curve..
Actually, the name spline itself is derived from elastic beams, so-called splines, that are used by draftsmen for laying out broad sweeping curves in a ship design. It is held in place by a number of heavy weights, and these physical splines assume a shape that minimizes the strain energy.
So let’s define now splines mathematically :
A curve s(u) is called spline of degree n with the knots , where and for any possible , if :
s(u) is n-r times differentiable at any r-fold knot, and s(u) is a polynomial of degree <= n over each knot interval , where .
It is sometimes common to refer to a spline of degree n as spline of order n+1.
It is desirable to write a spline s(u) as an affine combination of some control points , namely
Where the are the basis spline functions with a minimal support and certain properties, these functions are called B-splines basis functions.
So simply said, spline functions are constructed as linear combinations of B-splines with a set of control points.
Let’s now define the B-splines functions :
So as to define B-splines, we let to be a, for simplicity, bi infinite and strictly increasing sequence of knots, that means we have : , for all . We may define B-splines with these knots by the following recursion formula:
If , we have : otherwise .
and where .
It is clear that the definition is of recursion type.
We can use B-spline to approximate an unknown function, suppose we are given n + 1 data points and we would like to find a B-spline curve that follows the shape of the data polygon without containing the data points ( as we are doing approximation).
To do so, we need two more inputs, a number of the control points (h+1) and a degree p, where n > h >= p >= 1, this inequality must hold.
We mention here some of its properties :
Local modifications scheme : it means that changing the position of a control point P affects only the cure on that region.
Convex hull property: which means a B-spline curve is contained in the convex hull of its control polyline.
Back to our main topic :
A Bezier curve of degree m can be generalized as follows: Where is an interpolated point at parameter value , m is degree of Bezier curve and Pk is kth control point. So that we can generate n points ( where n is count of interpolating points) between first and last control points inclusive, the parameter is actually uniformly divided into n-1 intervals between 0 and 1 inclusive. So the equations of cubic Bezier curves may be derived from the equation above as follows : By the way, Bezier curve passes through its first and last control points which are and , and the middle control points, I.e and , they determine the shape of the curve.When using cubic Bezier to fit a given data, the first and the last control points of Bezier curve are simply the first and last point of the given input data segment, and actually this input data can be divided into many segments or we may just use it as one segment, but the middle control points, for our cubic Bezier must be determined so that our Bezier curve will fit the input data and give the best approximation, for this purpose we may use Least square method that gives us the best values of our middle control points that really minimize the squared distance between original and fitted data and is well suited for approximation, So simply, if we are given n data points; and are values of original and approximated points respectively, so we write the least square equations as follows :(3)
The equation (3) can be written as follows:
(4)
So, and can be determined by:
(5)
(6)
After solving Eq. (5) for and Eq. (6) for :
(7)
(8)
Where :
(9)
(10)
(11)
(12)(13)
After the calculations and finding the control points, the Bezier curves can be easily fitted to a given large number of data.
In our comparison, we will be using the sum of squared errors criterion to compare both approximation methods and analyze them briefly.
Let’s discuss the B-spline approximation, and by the way, approximation is more flexible than interpolation, because we do not only select a degree but also the number of control points.
The summary of our problem is the following, we are given n+1 data points and we would like to find a B-spline curve that follows the shape of given data, and without really containing the data points.
We have the following formula :Where are as we mentioned before, the h+1 unknown control points. We want the curve to pass the first and last data points, so we let Therefore, there are actually only h – 1 unknown control points , so taking this into account, the curve equations becomes the following:
Analytically, in this report, we will consider the least square fitting, as we did previously with Bezier curves, the question that arises here is about our measure of the error distance, the parameter corresponds to data point , so the distance between and the corresponding point of on the curve is , and since this distance consists of a square root which is not easy to handle.. we decided to use the squared distance , we can describe the sum of all squared error distances as :
So our goal here is the same as we did before, which is to find those control points such that the function f is minimized, in this way the approximation is done in the sense of least square.
And with some knowledge in linear algebra, we can minimize that sum and find the control points just like we did in Bezier part, and with the desired control points we get the best B-spline approximation using the curve fitting method mentioned previously.
Let’s have a brief aside comparison between both of Bezier and B-splines curves:Actually B-splines require more information which are the degree of the curve, and a knot vector. B-splines do have more complex theory than Bezier curves, but its worth it as it has more advantages. Let’s make it clear; First, a B-spline curve can be a Bezier curve. Second, B-splines do have all important properties that Bezier curves have, an other advantage is that B-spline curves provide more control flexibility than Bezier curves can do, for instance, the degree of a B-spline doesn’t depend on the number of control point while Bezier depends, which means that we can use lower degree curves and sill maintain a large number of control points, and we may change the position of a control point without totally changing the shape of the whole curve and this is called local modification property, in the other side, we know that the degree of Bezier curve depends on the number of control points, this comparison is important if we are planning to use the both techniques in function approximation, Bezier curves approximation would work well if the segment on which we approximate is relatively small, let’s say we have 4 control points, and we may use a curve fitting method like we mentioned before the least squares method, and we have a bezier cubic curve, and with the minimization we can make with the curve fitting, we can get a good approximation, but what if the segment is relatively larger, in this case we would need more control points, and as result the degree of the Bezier curve is getting higher, which is not a good thing, because the number of the calculations becomes larger which means that it is an expensive approach, in the other hand, we have the B-splines for this case, we can have many control points and with a lower degree, and if we do some curve fitting techniques, it would be more than fantastic.
Problem statement
In very simple words, a function approximation is about finding a function that closely matches approximates some target function based on some given data.
It’s very related to the problem of interpolation; In interpolation, the curve that interpolates passes through all the given data points, and as consequence, the interpolating curve may wiggle through our data points instead of following the data closely, and here the approximation technique is introduced to overcome this issue, and the approximating curve does not have to contain every point.
So let’s state the problem :
Given a set of data, find a cubic Bezier curve that approximates the given data.
As it is about approximating, a concept of error distance is used, that error distance is about the distance between a data point and its corresponding point on the approximating curve, so we minimize the sum of these error distances just like what we explained previously, so as a result, the approximating curve must follow the shape of the data closely.
Next, we demonstrate how our program solves this problem, we applied our approach to solve two approximation problems.
Program realization III
Our program is able to find four control points using a simple residual sum of squares (RSS) minimization, it just implements what we have explained mathematically.
We have used Java programming language, and Apache POI – the Java API for Microsoft documents, the Apache POI is a project that contains many subcomponents, such as HSSF (Horrible Spread Sheet Format) – reads and writes Microsoft Excel (XLS) format files, simply saying, this component allows us to write the output to a file of .xlsx format (Excel), and it is the we have used.
So let’s use the program to solve an approximation problem :
Input data (Approximating sin(x) on I = [0, 3]) :
x
y
0
0
0,5
0,4794
1
0,8414
1,5
0,9974
2
0,9092
2,5
0,5984
3
0,1411
Numerical results
We clearly see in our output, that the approximating cubic Bezier curve fits well our data, and the absolute error is relatively very small, which shows how a cubic Bezier curve can be used in an approximation problem and get good results.
Next we use our program to approximate data of cos(x) function on the interval [-1.5, 1.5]
Let’s use the program to solve another approximation problem :
Input data (Approximating cos(x) on I = [-1.5, 1.5]) :
x
y
-1.5
0,0707
-1
0,5403
-0.5
0,8775
0
1
0.5
0,8775
1
0,5403
1.5
0,0707
And the program’s output :
And again our approximation works and fits well and the error is relatively very small.
Conclusion
At the beginning of our project, we discussed Bezier curves and discussed their mathematical definition, explained and studied the Bezier curves, we studied some techniques such as the root finder algorithm of a cubic equation, the Cardano’s technique, which we have used to find coordinates of a point on cubic Bezier curve, we realized a program that implements the algorithm, after that we realized another program that plots the Bezier curve based on the given input control points.
We studied and discussed the theory and some related topics, such as the least squares approximation, Lagrange interpolation, and we have realized a Java program that implements these methods, we also discussed some theory directly and indirectly related to our topic.
After that, we returned to our main problem, stated the problem which is how one can use a cubic Bezier curve to solve an approximation problem, we stated that these curves are used in approximation which it concerns us more, curve fitting, where we simply try to find unknown points or values of a function using some known values, using the Bezier curves which are smooth and easy to draw, we used the least squares minimization approach to determine the control points so that our cubic Bezier curve approximates the best our data, we explained mathematically the approach, and we realized a program that can do it for us, using the Apache POI API that allowed us to write the output to a file of .xlsx format.
At the end we used our program to solve two approximation problems, and we got good numerical results that show clearly that our approximation method approach fits well.
References
https://en.wikipedia.org/wiki/B%C3%A9zier_curve
http://mathworld.wolfram.com/BezierCurve.html
http://www.moshplant.com/direct-or/bezier/math.html
http://www.ispacs.com/conferences/journals/cjac/001/cjac-001-007/
https://docs.oracle.com/javase/tutorial/
https://netbeans.org/
http://www.nordtech.ubm.ro/issues/2008/2008.01.09.pdf
http://www.mcs.csueastbay.edu/~malek/Class/Bezier.pdf
http://www.wow.com/wiki/Bezier_curve
http://web.williams.edu/Mathematics/sjmiller/public_html/BrownClasses/54/handouts/MethodLeastSquares.pdf
Appendix
Here is a part of the source code of our program:
This class encapsulates a Bezier curve
public class BezierCurve {
private double[] factorials;
public BezierCurve() {
initializeFactorials();
}
// We don’t need to calculate factorials at the runtime
private void initializeFactorials() {
//Lets fill up to 33!
factorials = new double[33];
factorials[0] = 1.0;
factorials[1] = 1.0;
factorials[2] = 2.0;
factorials[3] = 6.0;
factorials[4] = 24.0;
factorials[5] = 120.0;
factorials[6] = 720.0;
factorials[7] = 5040.0;
factorials[8] = 40320.0;
factorials[9] = 362880.0;
factorials[10] = 3628800.0;
factorials[11] = 39916800.0;
factorials[12] = 479001600.0;
factorials[13] = 6227020800.0;
factorials[14] = 87178291200.0;
factorials[15] = 1307674368000.0;
factorials[16] = 20922789888000.0;
factorials[17] = 355687428096000.0;
factorials[18] = 6402373705728000.0;
factorials[19] = 121645100408832000.0;
factorials[20] = 2432902008176640000.0;
factorials[21] = 51090942171709440000.0;
factorials[22] = 1124000727777607680000.0;
factorials[23] = 25852016738884976640000.0;
factorials[24] = 620448401733239439360000.0;
factorials[25] = 15511210043330985984000000.0;
factorials[26] = 403291461126605635584000000.0;
factorials[27] = 10888869450418352160768000000.0;
factorials[28] = 304888344611713860501504000000.0;
factorials[29] = 8841761993739701954543616000000.0;
factorials[30] = 265252859812191058636308480000000.0;
factorials[31] = 8222838654177922817725562880000000.0;
factorials[32] = 263130836933693530167218012160000000.0;
}
private double binomeN_I(int n, int i) {
double ni;
double a1 = factorial(n);
double a2 = factorial(i);
double a3 = factorial(n – i);
ni = a1 / (a2 * a3);
return ni;
}
Method that returns a factorial of given input n
private double factorial(int n) {
if (n < 0 || n > 32) {
return -1;
}
return factorials[n];
}
private double bernstein(int n, int i, double t) {
double basis;
double ti; // a variabe where we store t^i
double tni; // the same.. (1 – t)^i
// We check some known and specific values of t and i..
if (t == 0.0 && i == 0) {
ti = 1.0;
} else {
ti = Math.pow(t, i);
}
if (n == i && t == 1.0) {
tni = 1.0;
} else {
tni = Math.pow((1 – t), (n – i));
}
// We return the bernestein coefficient
basis = binomeN_I(n, i) * ti * tni;
return basis;
}
// it calculates and stores the values in the array p
public void bezier2D(double[] b, int cpts, double[] p) {
int numberOfPoints = (b.length) / 2;
int icounter, jcounter;
double step, t;
// We calculate the points of the curve
icounter = 0;
t = 0;
step = (double) 1.0 / (cpts – 1);
for (int i1 = 0; i1 != cpts; i1++) {
if ((1.0 – t) < 5e-6) {
t = 1.0;
}
jcounter = 0;
p[icounter] = 0.0;
p[icounter + 1] = 0.0;
for (int i = 0; i != numberOfPoints; i++) {
double basis = bernstein(numberOfPoints – 1, i, t);
p[icounter] += basis * b[jcounter];
p[icounter + 1] += basis * b[jcounter + 1];
jcounter = jcounter + 2;
}
icounter += 2;
t += step;
}
}
}
public class BezierJavaApp extends javax.swing.JFrame {
/**
* Creates new form BezierJavaApp
*/
private ArrayList<Double> pointsList = new ArrayList<>();
private BezierCurve bezierCurve = new BezierCurve();
private boolean needLine = false;
private Point x;
private Point y;
public BezierJavaApp() {
initComponents();
//jPanel1.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
}
private void initComponents() {
. . . // initialize graphical components
curvePanel.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
curvePanelMouseClicked(evt);
}
});
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
clearButton.setText(“Clear”);
clearButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
clearButtonActionPerformed(evt);
}
});
}
private void curvePanelMouseClicked(java.awt.event.MouseEvent evt) {
double X = evt.getPoint().getX();
double Y = evt.getPoint().getY();
pointsList.add(X);
pointsList.add(Y);
if (!needLine) {
needLine = true;
x = new Point((int) X, (int) Y);
} else {
y = new Point((int) X, (int) Y);
drawLine(x, y);
x = y;
}
Graphics2D g = (Graphics2D) this.curvePanel.getGraphics();
g.setColor(Color.red);
g.drawRect((int) evt.getPoint().getX(), (int) evt.getPoint().getY(), 4, 4);
this.curvePanel.revalidate();
}
// Method to draw a line.
private void drawLine(Point x, Point y) {
Graphics2D g = (Graphics2D) curvePanel.getGraphics();
g.setColor(Color.blue);
g.drawLine((int) x.getX(), (int) x.getY(), (int) y.getX(), (int) y.getY());
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// Let 1000 be the number of the points to draw..
final int POINTS_ON_CURVE = 1000;
Graphics2D g = (Graphics2D) this.curvePanel.getGraphics();
double[] ptind = new double[pointsList.size()];
double[] p = new double[POINTS_ON_CURVE];
copyTo(pointsList, ptind, pointsList.size());
bezierCurve.bezier2D(ptind, (POINTS_ON_CURVE) / 2, p);
// We draw the points
for (int i = 1; i != POINTS_ON_CURVE – 1; i += 2) {
g.setColor(Color.magenta);
g.drawRect((int) p[i + 1], (int) p[i], 1, 1);
}
}
// Method called to reset everything and clean the jpanel
private void reset() {
this.needLine = false;
curvePanel.updateUI();
this.pointsList.clear();
}
private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {
reset();
}
private void copyTo(ArrayList<Double> a, double[] b, int size) {
for (int i = 0; i < size; i++) {
b[i] = a.get(i);
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if (“Nimbus”.equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
…// handle exceptions..
}
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new BezierJavaApp().setVisible(true);
}
});
}
// Variables declaration – do not modify
private javax.swing.JButton clearButton;
private javax.swing.JPanel curvePanel;
private javax.swing.JButton jButton1;
}
Here is the source code for the console program :
public class Cardano {
static class Point {
double px;
double py;
}
final static int numberOfPoints = 4;
static Point[] controllPoints = new Point[numberOfPoints];
static Point[] coefficients = new Point[numberOfPoints];
static Point bezierPoint = new Point();
static double P, Q, K, A, B, squareRoot;
static double t, y;
public static void main(String[] args) {
allocateMemoryForPoints(); // Create objects (Points)
getInputs(); // Get the input(controllPoints) from the user.
doCalculation1(); // Calculate the coefficients for the polynomial.
printCubicEquation();//Print the cubic equation.
doCalculation2();//calulate t and By.
printFinalResult();//Print the final result.
}
private static void printFinalResult() {
System.out.println(” t = ” + t);
bezierPoint.py = coefficients[0].py * t * t * t + coefficients[1].py * t * t + coefficients[2].py * t + coefficients[3].py;
System.out.println(“By = ” + bezierPoint.py);
}
private static void doCalculation2() {
coefficients[0].py = -controllPoints[0].py + 3 * controllPoints[1].py – 3 * controllPoints[2].py + controllPoints[3].py;
coefficients[1].py = 3 * controllPoints[0].py – 6 * controllPoints[1].py + 3 * controllPoints[2].py;
coefficients[2].py = (-3) * controllPoints[0].py + 3 * controllPoints[1].py;
coefficients[3].py = controllPoints[0].py;
P = (3 * coefficients[0].px * coefficients[2].px – coefficients[1].px * coefficients[1].px) / (3 * coefficients[0].px * coefficients[0].px);
Q = (2 * coefficients[1].px * coefficients[1].px * coefficients[1].px – 9 * coefficients[0].px * coefficients[1].px * coefficients[2].px + 27 * coefficients[0].px * coefficients[0].px * coefficients[3].px)/(27 * coefficients[0].px * coefficients[0].px * coefficients[0].px);
K = (P/3) * (P/3) * (P/3) + (Q/2) * (Q/2);
squareRoot = Math.sqrt(K);
if ((-Q/2)+squareRoot>=0)
A = Math.pow(((-Q/2)+squareRoot),1./3.);
else {
A = Math.pow(Math.abs(((-Q/2)+squareRoot)),1./3.);
A = -A;
}
if ((-Q/2)-squareRoot>=0) B = Math.pow((-Q/2-squareRoot),1./3.);
else {
B = Math.pow(Math.abs((-Q/2-squareRoot)),1./3.);
B = -B;
}
y = A+B;
t = y – (coefficients[1].px/(3*coefficients[0].px));
}
private static void printCubicEquation() {
System.out.println(“The resulting cubic equation : “);
System.out.println( coefficients[0].px + “t^3 + ” + coefficients[1].px + “t^2 + ” + coefficients[2].px + “t + ” + coefficients[3].px + ” = 0″);
}
private static void doCalculation1() {
coefficients[0].px = -controllPoints[0].px + 3 * controllPoints[1].px – 3 * controllPoints[2].px + controllPoints[3].px;
coefficients[1].px = 3 * controllPoints[0].px – 6 * controllPoints[1].px + 3 * controllPoints[2].px;
coefficients[2].px = (-3) * controllPoints[0].px + 3 * controllPoints[1].px;
coefficients[3].px = controllPoints[0].px – bezierPoint.px;
}
private static void allocateMemoryForPoints() {
for(int k = 0; k<numberOfPoints; k++) {
controllPoints[k] = new Point();
coefficients[k] = new Point();
}
private static void getInputs() {
Scanner sc = new Scanner(System.in);
int i = 0;
while( i < numberOfPoints) {
System.out.println(“Input the coordinates (x,y) of the controll point : #” + (i+1));
controllPoints[i].px = sc.nextDouble();
controllPoints[i].py = sc.nextDouble();
i++;
}
System.out.println(“Input the x-coordinate of Bezier curve :”);
System.out.print(“Bx : “);
bezierPoint.px = sc.nextDouble();
}
And for the second program :
public class ApproximationMethods {
public static Betas leastSquaresMethod(Point[] points) {
double sumx = 0f, sumy = 0f, sumx2 = 0f;
int n = points.length;
for(int i = 0; i<n; i++ ){
sumx += points[i].getX();
sumy += points[i].getY();
sumx2 += points[i].getX() * points[i].getX();
}
double xbar = sumx / n;
double ybar = sumy / n;
// We compute summary statistics
double xxbar = 0f, yybar = 0f, xybar = 0f;
for (int i = 0; i < n; i++) {
xxbar += (points[i].getX() – xbar) * (points[i].getX() – xbar);
yybar += (points[i].getY() – ybar) * (points[i].getY() – ybar);
xybar += (points[i].getX() – xbar) * (points[i].getY() – ybar);
}
double beta1 = xybar / xxbar;
double beta0 = ybar – beta1 * xbar;
return new Betas(beta1, beta0);
}
public static class Betas {
public double a;
public double b;
public Betas(double a, double b) {
this.a = a;
this.b = b;
}
}
public static double[] findPolynomalFactorsLaGrangeInterpolationSecond(Point[] points){//double[] x, double[] y) {
int n = points.length;
double[][] data = new double[n][n];
double[] rhs = new double[n];
for (int i = 0; i < n; i++) {
double v = 1;
for (int j = 0; j < n; j++) {
data[i][n-j-1] = v;
v *= points[i].getX();
}
rhs[i] = points[i].getY();
}
// Solving m * s = b
Matrix m = new Matrix (data);
Matrix b = new Matrix (rhs, n);
Matrix s = m.solve (b);
return s.getRowPackedCopy();
}
}