mirror of https://github.com/CGAL/cgal
tests performed for points on a line in 2D
Doc: added definitions, did many fixes. IMPORTANT: sylvain: double-check the definitions, and precise the dimension and types available for each of your function. important change: I suggest to rename the function bounding_box to axis_aligned_bounding_box (min case later you will hack on the general one).
This commit is contained in:
parent
7e9a453443
commit
04826e29aa
|
|
@ -210,7 +210,12 @@ BEGIN
|
|||
POPUP "&Fit"
|
||||
BEGIN
|
||||
MENUITEM "&Line", ID_FIT_LINE
|
||||
MENUITEM "Debug", ID_FIT_DEBUG
|
||||
POPUP "Debug"
|
||||
BEGIN
|
||||
MENUITEM "Many tests for 2 points", ID_FIT_DEBUG
|
||||
MENUITEM "Many points on a line", ID_DEBUG_MANYTESTSFORNUMEROUSPOINTSONALINE
|
||||
|
||||
END
|
||||
END
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ BEGIN_MESSAGE_MAP(CpcaDlg, CDialog)
|
|||
ON_COMMAND(ID_RANDOM_HORIZONTALLINE, OnRandomHorizontalline)
|
||||
ON_COMMAND(ID_RANDOM_VERTICALLINE, OnRandomVerticalline)
|
||||
ON_COMMAND(ID_FIT_DEBUG, OnFitDebug)
|
||||
ON_COMMAND(ID_DEBUG_MANYTESTSFORNUMEROUSPOINTSONALINE, OnDebugManytestsfornumerouspointsonaline)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
|
|
@ -469,13 +470,35 @@ void CpcaDlg::OnRandomVerticalline()
|
|||
}
|
||||
|
||||
void CpcaDlg::OnFitDebug()
|
||||
{
|
||||
BeginWaitCursor();
|
||||
for(int i=0;i<10000;i++)
|
||||
{
|
||||
m_points.clear();
|
||||
double x1 = (double)rand() / (double)RAND_MAX;
|
||||
double y1 = (double)rand() / (double)RAND_MAX;
|
||||
double x2 = (double)rand() / (double)RAND_MAX;
|
||||
double y2 = (double)rand() / (double)RAND_MAX;
|
||||
m_points.push_back(Point_2(x1,y1));
|
||||
m_points.push_back(Point_2(x2,y2));
|
||||
OnFitLine();
|
||||
}
|
||||
EndWaitCursor();
|
||||
InvalidateRect(NULL,FALSE);
|
||||
}
|
||||
|
||||
void CpcaDlg::OnDebugManytestsfornumerouspointsonaline()
|
||||
{
|
||||
BeginWaitCursor();
|
||||
m_points.clear();
|
||||
|
||||
// random line (y = ax + b)
|
||||
double a = (double)rand() / (double)RAND_MAX;
|
||||
double b = (double)rand() / (double)RAND_MAX;
|
||||
for(int i=0;i<10000;i++)
|
||||
{
|
||||
double x = (double)rand() / (double)RAND_MAX;
|
||||
double y = (double)rand() / (double)RAND_MAX;
|
||||
double y = a * x + b;
|
||||
m_points.push_back(Point_2(x,y));
|
||||
}
|
||||
OnFitLine();
|
||||
|
|
|
|||
|
|
@ -80,4 +80,5 @@ public:
|
|||
afx_msg void OnRandomHorizontalline();
|
||||
afx_msg void OnRandomVerticalline();
|
||||
afx_msg void OnFitDebug();
|
||||
afx_msg void OnDebugManytestsfornumerouspointsonaline();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,13 +20,15 @@
|
|||
#define ID_RANDOM_HORIZONTALLINE 32781
|
||||
#define ID_RANDOM_VERTICALLINE 32782
|
||||
#define ID_FIT_DEBUG 32783
|
||||
#define ID_FIT_DEBUG32784 32784
|
||||
#define ID_DEBUG_MANYTESTSFORNUMEROUSPOINTSONALINE 32785
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 132
|
||||
#define _APS_NEXT_COMMAND_VALUE 32784
|
||||
#define _APS_NEXT_COMMAND_VALUE 32786
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,20 +1,5 @@
|
|||
This \cgal\ package provides functions to compute global informations
|
||||
on the shape of a set of 2D or 3D objects such as points. It provides the computation of bounding boxes, centroids of point sets, barycenters of weighted point sets, as well as linear least squares fitting.
|
||||
|
||||
Linear least squares fitting approximates a set of objects by a linear
|
||||
sub-space such as a line or a plane. Formally, given a set of points in $R^d$, linear least squares fitting amounts
|
||||
to find the linear sub-space of $R^d$ which minimizes the sum of squared
|
||||
distances from the points to their projection onto this linear sub-space. This
|
||||
problem is equivalent to search for the linear sub-space which maximizes the
|
||||
variance of projected points, the latter being obtained by eigen decomposition
|
||||
of the covariance matrix. Eigenvectors corresponding to large eigenvalues are
|
||||
the directions in which the data has strong component, or equivalently large
|
||||
variance. If eigenvalues are the same there is no preferable sub-space.
|
||||
This package implements the linear least squares fitting for
|
||||
several objects of a \cgal\ 2D or 3D kernel: the best fit 2D line for 2D
|
||||
point sets, and the best fit 3D line or plane for point and
|
||||
triangle sets. The object sets are specified by iterator ranges of
|
||||
containers.
|
||||
on the shape of a set of 2D or 3D objects such as points. It provides the computation of axis-aligned bounding boxes, centroids of point sets, barycenters of weighted point sets, as well as linear least squares fitting for point sets in 2D, and point sets as well as triangle sets in 3D. The sets are specified by iterator ranges of containers.\\
|
||||
|
||||
\begin{center}
|
||||
\label{fit}
|
||||
|
|
@ -23,7 +8,7 @@ containers.
|
|||
\includegraphics[width=1.0\textwidth]{Principal_component_analysis/fit}
|
||||
\end{ccTexOnly}
|
||||
\begin{ccHtmlOnly}
|
||||
<img width="45%" border=0 src="./fit.png"><P>
|
||||
<img width="100%" border=0 src="./fit.png"><P>
|
||||
\end{ccHtmlOnly}
|
||||
% Title
|
||||
\begin{figure}[h]
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
\subsection{Bounding Box of a Point Set}
|
||||
|
||||
In the following example we use \stl\ containers of 2D and 3D points, and
|
||||
compute their bounding box. The kernel from which the input points
|
||||
compute their axis-aligned bounding box. The kernel from which the input points
|
||||
come is automatically deduced by the function.
|
||||
|
||||
\ccIncludeExampleCode{Principal_component_analysis/bounding_box.C}
|
||||
|
|
|
|||
|
|
@ -15,20 +15,30 @@
|
|||
\subsection*{Summary}
|
||||
|
||||
This \cgal\ package provides functions to compute global informations
|
||||
on the shape of a set of 2D or 3D objects such as points. It provides the computation of bounding boxes, centroids of point sets, barycenters of weighted point sets, as well as linear least squares fitting. It assumes the set of kernel primitive elements to be stored into an iterator range of a container.
|
||||
on the shape of a set of 2D or 3D objects such as points. It provides the computation of axis-aligned bounding boxes for point sets, centroids of point sets and triangle sets in 2D and 3D, barycenters of weighted point sets, as well as linear least squares fitting for point sets in 2D, and point sets and triangle sets in 3D. It assumes the set of kernel primitive elements to be stored into an iterator range of a container.
|
||||
|
||||
\subsection*{Definitions}
|
||||
|
||||
\subsection*{Definition}
|
||||
Given a point set in $R^d$, linear least squares fitting amounts to
|
||||
find the linear sub-space of $R^d$ which minimizes the sum of squared
|
||||
A \emph{bounding box} for a set of objects is a cuboid that completely
|
||||
contains the set. An \emph{axis-aligned bounding box} is a bounding box
|
||||
aligned with the axes of the coordinate system.\\
|
||||
|
||||
A \emph{centroid} is defined as average of position. A \emph{barycenter} of weighted point sets is defined as weighted average of position. When all weights are equal the barycenter coincides with the centroid.\\
|
||||
|
||||
Given a point set, \emph{linear least squares fitting} amounts to
|
||||
find the linear sub-space which minimizes the sum of squared
|
||||
distances from the points to their projection onto this linear
|
||||
sub-space. This problem is equivalent to search for the linear
|
||||
sub-space which maximizes the variance of projected points, the latter
|
||||
being obtained by eigen decomposition of the covariance
|
||||
matrix. Eigenvectors corresponding to large eigenvalues are the
|
||||
matrix of the point set. Eigenvectors corresponding to large eigenvalues are the
|
||||
directions in which the data has strong component, or equivalently
|
||||
large variance. If eigenvalues are the same there is no preferable
|
||||
sub-space.
|
||||
sub-space.\\
|
||||
|
||||
Given a triangle set, \emph{linear least squares fitting} amounts to find the linear sub-space which minimizes the sum of squared
|
||||
distances from all points in the set to their projection onto this linear
|
||||
sub-space. This problem is equivalent to the one of fitting a linear sub-space to a point set, except that the covariance matrix is now derived from a continuous integral over the triangles instead of a discrete sum over the points.
|
||||
|
||||
\ccHeading{Functions}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@
|
|||
#include <list>
|
||||
#include <iostream>
|
||||
|
||||
typedef double FT;
|
||||
typedef CGAL::Cartesian<FT> K;
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::Point_3 Point_3;
|
||||
typedef double FT;
|
||||
typedef CGAL::Cartesian<FT> K;
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::Point_3 Point_3;
|
||||
|
||||
int main()
|
||||
{
|
||||
// bounding_box of 2D points
|
||||
// axis-aligned bounding box of 2D points
|
||||
std::list<Point_2> points_2;
|
||||
points_2.push_back(Point_2(1.0, 0.0));
|
||||
points_2.push_back(Point_2(2.0, 2.0));
|
||||
|
|
@ -22,7 +22,7 @@ int main()
|
|||
K::Iso_rectangle_2 c2 = CGAL::bounding_box(points_2.begin(), points_2.end());
|
||||
std::cout << c2 << std::endl;
|
||||
|
||||
// bounding_box of 3D points
|
||||
// axis-aligned bounding box of 3D points
|
||||
std::list<Point_3> points_3;
|
||||
points_3.push_back(Point_3(1.0, 0.0, 0.5));
|
||||
points_3.push_back(Point_3(2.0, 2.0, 1.2));
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@ CGAL_BEGIN_NAMESPACE
|
|||
|
||||
namespace CGALi {
|
||||
|
||||
// extract eigenvalues and eigenvectors from a 2x2 symmetric matrix.
|
||||
// Note: involves a square root.
|
||||
// extract eigenvalues and eigenvectors from a 2x2 symmetric
|
||||
// positive definite matrix.
|
||||
// Note: computations involve a square root.
|
||||
// Matrix numbering:
|
||||
// a b
|
||||
// b c
|
||||
|
|
@ -48,6 +49,8 @@ namespace CGALi {
|
|||
FT c = matrix[2];
|
||||
FT p = c*c - 2*a*c + 4*b*b + a*a;
|
||||
|
||||
CGAL_assertion(a >= 0.0 && c >= 0.0);
|
||||
|
||||
// degenerate or isotropic case
|
||||
if(p == 0.0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -152,9 +152,6 @@ fitting_plane_3(const typename K::FT covariance[6], // covariance matrix
|
|||
FT eigen_values[3];
|
||||
FT eigen_vectors[9];
|
||||
eigen_symmetric<FT>(covariance,3,eigen_vectors,eigen_values);
|
||||
CGAL_assertion(eigen_values[0] >= 0.0 &&
|
||||
eigen_values[1] >= 0.0 &&
|
||||
eigen_values[2] >= 0.0);
|
||||
|
||||
// check unicity and build fitting line accordingly
|
||||
if(eigen_values[0] != eigen_values[1] &&
|
||||
|
|
@ -199,9 +196,6 @@ fitting_line_3(const typename K::FT covariance[6], // covariance matrix
|
|||
FT eigen_values[3];
|
||||
FT eigen_vectors[9];
|
||||
eigen_symmetric<FT>(covariance,3,eigen_vectors,eigen_values);
|
||||
CGAL_assertion(eigen_values[0] >= 0.0 &&
|
||||
eigen_values[1] >= 0.0 &&
|
||||
eigen_values[2] >= 0.0);
|
||||
|
||||
// check unicity and build fitting line accordingly
|
||||
if(eigen_values[0] != eigen_values[1])
|
||||
|
|
|
|||
Loading…
Reference in New Issue