mirror of https://github.com/CGAL/cgal
added: graphical output to `CGAL_Window_stream'
added: product file `include/CGAL/IO/Conic_2_Window_stream.h' changed: use of local `cgal.bib' (in `doc_tex/...')
This commit is contained in:
parent
552325f945
commit
8c4cfd3146
|
|
@ -886,110 +886,110 @@ As before, if $\E$ is not an ellipse, the result is meaningless.
|
|||
@end
|
||||
|
||||
@! ---------------------------------------------------------------------------
|
||||
@!subsubsection{Output to {\tt CGAL\_Window\_stream}}
|
||||
@subsubsection{Output to {\tt CGAL\_Window\_stream}}
|
||||
@! ---------------------------------------------------------------------------
|
||||
@!
|
||||
@! We provide an operator to write a conic to a
|
||||
@! @prg{CGAL_Window_stream}. @! The function is not extraordinarily
|
||||
@! efficient but simple (and works without `understanding' the conic;
|
||||
@! other methods -- like the one by Maxwell \& Baker -- need to
|
||||
@! determine the conic type first, compute start values etc.). The
|
||||
@! method works in image space, proceeding in two phases.
|
||||
@!
|
||||
@! Phase 1 draws the conic in $x$-direction. This means that the width
|
||||
@! of the output window is scanned pixel-wise, for any $x$-value
|
||||
@! computing the at most two corresponding values $y_1,y_2$ such that
|
||||
@! $(x,y_1),(x,y_2)\in \C$. (This is done by solving a quadratic
|
||||
@! equation). The resulting pixels are stored for output, which is
|
||||
@! triggered after all $x$-values have been processed in this way.
|
||||
@!
|
||||
@! Phase 2 draws the conic in $y$-direction, proceeding
|
||||
@! similarly. Phases 1 and 2 together ensure that there are no gaps in
|
||||
@! the drawn curve(s).
|
||||
@!
|
||||
@!macro <CGAL_Conic_2 Window_stream output> = @begin
|
||||
@! template < class R >
|
||||
@! CGAL_Window_stream& operator<< (CGAL_Window_stream &win,
|
||||
@! const CGAL_Conic_2<R> &c)
|
||||
@! {
|
||||
@! // length of a pixel in win-coordinates
|
||||
@! double pixel = 1/win.scale();
|
||||
@!
|
||||
@! // pixel dimensions of win
|
||||
@! int width = (int)((win.xmax() - win.xmin()) * win.scale()) + 1,
|
||||
@! height = (int)((win.ymax() - win.ymin()) * win.scale()) + 1,
|
||||
@! dim = (width > height) ? width : height;
|
||||
@!
|
||||
@! // pixel coordinates, stored for faster output
|
||||
@! double *X = new double [2*dim];
|
||||
@! double *Y = new double [2*dim];
|
||||
@!
|
||||
@! // actual number of pixels to be drawn
|
||||
@! int pixels;
|
||||
@!
|
||||
@! // conic coordinates
|
||||
@! double r = CGAL_to_double (c.r()),
|
||||
@! s = CGAL_to_double (c.s()),
|
||||
@! t = CGAL_to_double (c.t()),
|
||||
@! u = CGAL_to_double (c.u()),
|
||||
@! v = CGAL_to_double (c.v()),
|
||||
@! w = CGAL_to_double (c.w());
|
||||
@!
|
||||
@! // Phase I: draw in x-direction
|
||||
@! pixels = 0;
|
||||
@! // solve conic equation for y
|
||||
@! if (s != 0.0)
|
||||
@! for (double x = win.xmin(); x <= win.xmax(); x+=pixel) {
|
||||
@! double discr = (t*t-4.0*r*s)*(x*x) + (2.0*t*v-4.0*s*u)*x +
|
||||
@! v*v - 4.0*s*w;
|
||||
@! if (discr >= 0.0) {
|
||||
@! double y1 = (-t*x - v - sqrt(discr))/(2.0*s);
|
||||
@! double y2 = (-t*x - v + sqrt(discr))/(2.0*s);
|
||||
@! X[pixels] = x; Y[pixels++] = y1;
|
||||
@! X[pixels] = x; Y[pixels++] = y2;
|
||||
@! }
|
||||
@! }
|
||||
@! else
|
||||
@! for (double x = win.xmin(); x <= win.xmax(); x+=pixel) {
|
||||
@! double denom = t*x + v;
|
||||
@! if (denom != 0.0) {
|
||||
@! double y = -(r*x*x + u*x + w)/denom;
|
||||
@! X[pixels] = x; Y[pixels++] = y;
|
||||
@! }
|
||||
@! }
|
||||
@! win.draw_pixels (pixels, X, Y);
|
||||
@!
|
||||
@! // Phase II: draw in y-direction
|
||||
@! pixels = 0;
|
||||
@! // solve conic equation for x
|
||||
@! if (r != 0.0)
|
||||
@! for (double y = win.ymin(); y <= win.ymax(); y+=pixel) {
|
||||
@! double discr = (t*t-4.0*r*s)*(y*y) + (2.0*t*u-4.0*r*v)*y +
|
||||
@! u*u - 4.0*r*w;
|
||||
@! if (discr >= 0.0) {
|
||||
@! double x1 = (-t*y - u - sqrt(discr))/(2.0*r);
|
||||
@! double x2 = (-t*y - u + sqrt(discr))/(2.0*r);
|
||||
@! X[pixels] = x1; Y[pixels++] = y;
|
||||
@! X[pixels] = x2; Y[pixels++] = y;
|
||||
@! }
|
||||
@! }
|
||||
@! else
|
||||
@! for (double y = win.ymin(); y <= win.ymax(); y+=pixel) {
|
||||
@! double denom = t*y + u;
|
||||
@! if (denom != 0.0) {
|
||||
@! double x = -(s*y*y + v*y + w)/denom;
|
||||
@! X[pixels] = x; Y[pixels++] = y;
|
||||
@! }
|
||||
@! }
|
||||
@! win.draw_pixels (pixels, X, Y);
|
||||
@!
|
||||
@! delete [] Y;
|
||||
@! delete [] X;
|
||||
@!
|
||||
@! return win;
|
||||
@! }
|
||||
@!
|
||||
@!@end
|
||||
|
||||
We provide an operator to write a conic to a
|
||||
@prg{CGAL_Window_stream}. The function is not extraordinarily
|
||||
efficient but simple (and works without `understanding' the conic;
|
||||
other methods -- like the one by Maxwell \& Baker -- need to
|
||||
determine the conic type first, compute start values etc.). The
|
||||
method works in image space, proceeding in two phases.
|
||||
|
||||
Phase 1 draws the conic in $x$-direction. This means that the width
|
||||
of the output window is scanned pixel-wise, for any $x$-value
|
||||
computing the at most two corresponding values $y_1,y_2$ such that
|
||||
$(x,y_1),(x,y_2)\in \C$. (This is done by solving a quadratic
|
||||
equation). The resulting pixels are stored for output, which is
|
||||
triggered after all $x$-values have been processed in this way.
|
||||
|
||||
Phase 2 draws the conic in $y$-direction, proceeding
|
||||
similarly. Phases 1 and 2 together ensure that there are no gaps in
|
||||
the drawn curve(s).
|
||||
|
||||
@macro<Conic_2 graphical output operator> = @begin
|
||||
#ifdef CGAL_CONIC_2_H
|
||||
#ifndef CGAL_IO_WINDOW_STREAM_CONIC_2
|
||||
#define CGAL_IO_WINDOW_STREAM_CONIC_2
|
||||
|
||||
template< class R >
|
||||
CGAL_Window_stream&
|
||||
operator << ( CGAL_Window_stream &ws, const CGAL_Conic_2<R>& c)
|
||||
{
|
||||
// length of a pixel in window-coordinates
|
||||
double pixel = 1/ws.scale();
|
||||
|
||||
// pixel dimensions of window
|
||||
int width = (int)((ws.xmax() - ws.xmin()) * ws.scale()) + 1,
|
||||
height = (int)((ws.ymax() - ws.ymin()) * ws.scale()) + 1,
|
||||
dim = CGAL_max( width, height);
|
||||
|
||||
// pixel coordinates, stored for faster output
|
||||
double *X = new double [2*dim];
|
||||
double *Y = new double [2*dim];
|
||||
|
||||
// actual number of pixels to be drawn
|
||||
int pixels;
|
||||
|
||||
// conic coordinates
|
||||
double r = CGAL_to_double (c.r()),
|
||||
s = CGAL_to_double (c.s()),
|
||||
t = CGAL_to_double (c.t()),
|
||||
u = CGAL_to_double (c.u()),
|
||||
v = CGAL_to_double (c.v()),
|
||||
w = CGAL_to_double (c.w());
|
||||
|
||||
// Phase I (drawing in x-direction)
|
||||
pixels = 0;
|
||||
// solve conic equation for y
|
||||
if (s != 0.0)
|
||||
for (double x = ws.xmin(); x <= ws.xmax(); x+=pixel) {
|
||||
double discr = (t*t-4.0*r*s)*(x*x) + (2.0*t*v-4.0*s*u)*x +
|
||||
v*v - 4.0*s*w;
|
||||
if (discr >= 0.0) {
|
||||
double y1 = (-t*x - v - sqrt(discr))/(2.0*s);
|
||||
double y2 = (-t*x - v + sqrt(discr))/(2.0*s);
|
||||
X[pixels] = x; Y[pixels++] = y1;
|
||||
X[pixels] = x; Y[pixels++] = y2; } }
|
||||
else
|
||||
for (double x = ws.xmin(); x <= ws.xmax(); x+=pixel) {
|
||||
double denom = t*x + v;
|
||||
if (denom != 0.0) {
|
||||
double y = -(r*x*x + u*x + w)/denom;
|
||||
X[pixels] = x; Y[pixels++] = y; } }
|
||||
ws.draw_pixels (pixels, X, Y);
|
||||
|
||||
// Phase II (drawing in y-direction)
|
||||
pixels = 0;
|
||||
// solve conic equation for x
|
||||
if (r != 0.0)
|
||||
for (double y = ws.ymin(); y <= ws.ymax(); y+=pixel) {
|
||||
double discr = (t*t-4.0*r*s)*(y*y) + (2.0*t*u-4.0*r*v)*y +
|
||||
u*u - 4.0*r*w;
|
||||
if (discr >= 0.0) {
|
||||
double x1 = (-t*y - u - sqrt(discr))/(2.0*r);
|
||||
double x2 = (-t*y - u + sqrt(discr))/(2.0*r);
|
||||
X[pixels] = x1; Y[pixels++] = y;
|
||||
X[pixels] = x2; Y[pixels++] = y; } }
|
||||
else
|
||||
for (double y = ws.ymin(); y <= ws.ymax(); y+=pixel) {
|
||||
double denom = t*y + u;
|
||||
if (denom != 0.0) {
|
||||
double x = -(s*y*y + v*y + w)/denom;
|
||||
X[pixels] = x; Y[pixels++] = y; } }
|
||||
ws.draw_pixels (pixels, X, Y);
|
||||
|
||||
// free memory
|
||||
delete[] Y;
|
||||
delete[] X;
|
||||
|
||||
return( ws);
|
||||
}
|
||||
|
||||
#endif // CGAL_IO_WINDOW_STREAM_CONIC_2
|
||||
#endif // CGAL_CONIC_2_H
|
||||
@end
|
||||
|
||||
|
||||
@! ---------------------------------------------------------------------------
|
||||
@section{Class Templates {\tt CGAL\_ConicHPA2<PT,DA>}
|
||||
|
|
@ -3218,6 +3218,9 @@ included before that.
|
|||
#endif
|
||||
|
||||
@<CGAL_Optimisation_ellipse_2 declaration>
|
||||
#ifndef CGAL_IO_FORWARD_DECL_WINDOW_STREAM_H
|
||||
#include <CGAL/IO/forward_decl_window_stream.h>
|
||||
#endif
|
||||
@<CGAL_Conic_2 interface and implementation>
|
||||
|
||||
#ifndef CGAL_NO_OSTREAM_INSERT_CONIC_2
|
||||
|
|
@ -3294,6 +3297,29 @@ Here is the class @prg{CGAL_ConicHPA2<PT,DA>}\ldots
|
|||
@<end of file line>
|
||||
@end
|
||||
|
||||
@! ----------------------------------------------------------------------------
|
||||
@! Conic_2_Window_stream.h
|
||||
@! ----------------------------------------------------------------------------
|
||||
|
||||
\subsection{Conic\_2\_Window\_stream.h}
|
||||
@file <include/CGAL/IO/Conic_2_Window_stream.h> = @begin
|
||||
@<file header>(
|
||||
"include/CGAL/IO/Conic_2_Window_stream.h",
|
||||
"graphical output to `leda_window' for Conic_2 algo.")
|
||||
|
||||
// Each of the following operators is individually
|
||||
// protected against multiple inclusion.
|
||||
|
||||
// Window_stream I/O operators
|
||||
// ===========================
|
||||
|
||||
// Conic_2
|
||||
// -------
|
||||
@<Conic_2 graphical output operator>
|
||||
|
||||
@<end of file line>
|
||||
@end
|
||||
|
||||
@! ----------------------------------------------------------------------------
|
||||
@! File Header
|
||||
@! ----------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue