diff --git a/Packages/Min_ellipse_2/web/Conic_2.aw b/Packages/Min_ellipse_2/web/Conic_2.aw index 0e83efb4c9d..6e3c4fc3cea 100644 --- a/Packages/Min_ellipse_2/web/Conic_2.aw +++ b/Packages/Min_ellipse_2/web/Conic_2.aw @@ -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 = @begin -@! template < class R > -@! CGAL_Window_stream& operator<< (CGAL_Window_stream &win, -@! const CGAL_Conic_2 &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 = @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& 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} @@ -3218,6 +3218,9 @@ included before that. #endif @ +#ifndef CGAL_IO_FORWARD_DECL_WINDOW_STREAM_H +#include +#endif @ #ifndef CGAL_NO_OSTREAM_INSERT_CONIC_2 @@ -3294,6 +3297,29 @@ Here is the class @prg{CGAL_ConicHPA2}\ldots @ @end +@! ---------------------------------------------------------------------------- +@! Conic_2_Window_stream.h +@! ---------------------------------------------------------------------------- + +\subsection{Conic\_2\_Window\_stream.h} +@file = @begin + @( + "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 + // ------- + @ + + @ +@end + @! ---------------------------------------------------------------------------- @! File Header @! ----------------------------------------------------------------------------