Boost logo

Boost-Commit :

From: jakevoytko_at_[hidden]
Date: 2007-05-28 20:19:42


Author: jakevoytko
Date: 2007-05-28 20:19:41 EDT (Mon, 28 May 2007)
New Revision: 4342
URL: http://svn.boost.org/trac/boost/changeset/4342

Log:
Prototype code with name change as suggested by Paul Bristow. Compiles with Visual Studio 2005.

Added:
   sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_instruction.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot_instruction.hpp

Added: sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp 2007-05-28 20:19:41 EDT (Mon, 28 May 2007)
@@ -0,0 +1,321 @@
+// svg.hpp
+
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// -----------------------------------------------------------------
+
+#ifndef _SVG_HPP
+#define _SVG_HPP
+
+
+#include <vector>
+#include <ostream>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+
+#include "svg_instruction.hpp"
+
+namespace boost {
+namespace svg {
+
+/*The lines in the beginning of document store the xml document in
+the following format:
+
+<?xml version=...
+<!Doctype svg...
+<svg width="...
+<g
+ Style line.. optional
+>
+
+*/
+
+enum {SVG_XML_HEADER, SVG_XML_DOCTYPE, SVG_OPEN, SVG_G_OPEN, SVG_G_STROKE,
+ SVG_G_FILL, SVG_G_CLOSE};
+
+class svg
+{
+private:
+ std::vector<std::string> document;
+
+ std::ostream *s_out;
+
+ void _write_header();
+
+ //Don't let people initialize this class
+ //without specifying the stream. I can't think
+ //of a reasonable default.
+ svg();
+
+protected:
+ unsigned int x_size;
+ unsigned int y_size;
+ void _check_size();
+ void _size(unsigned int, unsigned int);
+
+ void _write();
+ void _point(double, double);
+ void _line(double, double, double, double);
+ void _text(double, double, std::string);
+ void _line_color(svg_color);
+
+public:
+ svg(const std::string&);
+
+ virtual ~svg();
+ svg(const svg&);
+ svg& operator=(const svg&);
+
+ void operator<<(const svg_instruction&);
+
+ void operator<<(const svg_point&);
+
+ void operator<<(const svg_line&);
+ void operator<<(const svg_text&);
+
+ void operator<<(const svg_line_color&);
+
+ friend std::ostream& operator<<(std::ostream&, const svg&);
+};
+
+// -----------------------------------------------------------------
+// Constructors will be added so that the user can specify
+// a stream instead of a filename
+// -----------------------------------------------------------------
+svg::svg(const std::string& fname)
+ :s_out(new std::ofstream(fname.c_str()))
+{
+ _write_header();
+}
+
+svg::~svg()
+{
+ delete s_out;
+}
+
+//specify a new stream after the copy
+svg::svg(const svg& rhs)
+{
+ x_size = rhs.x_size;
+ y_size = rhs.y_size;
+ document = rhs.document;
+
+}
+
+// -----------------------------------------------------------------
+// Processes the svg_instructions
+// This allows the user to easily enter information:
+//
+// my_image<<color(RED)<<line(x1,y1,x2,y2)<<write();
+//
+// is the eventual goal for the interface to the svg object
+// -----------------------------------------------------------------
+void svg::operator<<(const svg_instruction& rhs)
+{
+ switch(rhs.i_type)
+ {
+ case SVG_WRITE:
+ _check_size();
+ _write();
+ break;
+ }
+}
+
+// -----------------------------------------------------------------
+// Stream operator to eventually stick data together in a stream-
+// like interface
+// -----------------------------------------------------------------
+void svg::operator<<(const svg_point &rhs)
+{
+ switch(rhs.i_type)
+ {
+ case SVG_SIZE:
+ _size((unsigned int)rhs.x, (unsigned int)rhs.y);
+ break;
+ case SVG_POINT:
+ _point(rhs.x, rhs.y);
+ }
+}
+
+void svg::operator<<(const svg_line &rhs)
+{
+ _line(rhs.x1, rhs.y1, rhs.x2, rhs.y2);
+}
+
+void svg::operator<<(const svg_text &rhs)
+{
+ _text(rhs.x, rhs.y, rhs.text);
+}
+
+void svg::operator<<(const svg_line_color &rhs)
+{
+ _line_color(rhs.col);
+}
+
+// -----------------------------------------------------------------
+// Internal function to write the data to a specified stream
+// TODO: allow other streams than a file stream
+// -----------------------------------------------------------------
+void svg::_write()
+{
+ document.push_back("</g>");
+ document.push_back("</svg>");
+
+ std::copy(document.begin(), document.end(),
+ std::ostream_iterator<std::string>(*s_out, "\n"));
+}
+
+// -----------------------------------------------------------------
+// This prints the svg header into the document
+// -----------------------------------------------------------------
+void svg::_write_header()
+{
+ document.push_back("<?xml version=\"1.0\" standalone=\"no\"?>");
+ document.push_back((std::string)"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" "+
+ "\"http://www.w3.org/graphics/svg/1.1/dtd/svg11.dtd\">");
+}
+
+// -----------------------------------------------------------------
+// Writes the information about the size of the file to the document
+// TODO: allow other unit identifiers
+// -----------------------------------------------------------------
+void svg::_size(unsigned int x, unsigned int y)
+{
+ x_size = x;
+ y_size = y;
+
+ std::stringstream fmt;
+ std::string to_write;
+
+ fmt<<"<svg width=\""<<x<<"\" height =\""
+ <<y<<"\" version=\"1.1\""
+ <<" xmlns=\"http://www.w3.org/2000/svg\">";
+
+ std::getline(fmt, to_write);
+
+ //if nothing has been written to the document yet, append
+ if(document.size() == 2)
+ {
+ document.push_back(to_write);
+
+ document.push_back("<g ");
+ document.push_back("");
+ document.push_back("");
+ document.push_back(">");
+ }
+
+ //otherwise, we are changing existing information
+ else
+ document[2] = to_write;
+}
+
+// -----------------------------------------------------------------
+// This makes sure that the size of the svg image has been written
+// before we do any other kind of work building the image
+// -----------------------------------------------------------------
+void svg::_check_size()
+{
+ if(document.size() < 3)
+ {
+ std::string to_write = "<svg width=\"100\" height =\"100\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">";
+
+ document.push_back(to_write);
+
+ document.push_back("<g ");
+
+ //optional style line
+ document.push_back("");
+ document.push_back("");
+ document.push_back(">");
+ }
+}
+
+// -----------------------------------------------------------------
+// Writes the information about points to the document
+// Since a point is not visible, we are actually drawing small
+// circles
+// TODO: allow other unit identifiers
+// -----------------------------------------------------------------
+void svg::_point(double x, double y)
+{
+ std::stringstream fmt;
+ std::string to_write;
+
+ fmt<<"<circle cx=\""<<x<<"\" cy =\""
+ <<y<<"\" r=\"5\" "
+ <<"fill=\"red\"/>";
+
+ std::getline(fmt, to_write);
+
+ document.push_back(to_write);
+}
+
+// -----------------------------------------------------------------
+// Writes the information about lines to the document
+// TODO: allow other unit identifiers
+// TODO: Allow other line thicknesses
+// TODO: Allow other line colors
+// -----------------------------------------------------------------
+void svg::_line(double x1, double y1, double x2, double y2)
+{
+ std::stringstream fmt;
+ std::string to_write;
+ //<line x1="000" y1="000" x2="000" y2="000" stroke="black"/>
+ fmt<< "<line x1=\""<<x1<<"\""
+ <<" y1 =\""<<y1<<"\" "
+ <<" x2 =\""<<x2<<"\" "
+ <<" y2 =\""<<y2<<"\"/>";
+
+ getline(fmt, to_write);
+
+ document.push_back(to_write);
+}
+
+// -----------------------------------------------------------------
+// Writes the information about lines to the document
+// TODO: allow different fonts and font sizes
+// -----------------------------------------------------------------
+void svg::_text(double x, double y, std::string text)
+{
+ std::stringstream fmt;
+ std::string to_write;
+
+ fmt<<"<text x=\""<<x<<"\""
+ <<" y=\""<<y<<"\" "
+ <<" font-family=\"Veranda\" font-size=\"12\" fill=\"black\">"
+ << text
+ <<" </text>";
+
+ getline(fmt, to_write);
+
+ document.push_back(to_write);
+}
+
+// -----------------------------------------------------------------
+// TODO: Add all of the colors that are supported by the SVG format
+// -----------------------------------------------------------------
+void svg::_line_color(svg_color col)
+{
+ switch(col)
+ {
+ case BLACK:
+ document[SVG_G_STROKE] = "stroke = \"black\"";
+ break;
+ case GRAY:
+ document[SVG_G_STROKE] = "stroke = \"gray\"";
+ break;
+ case RED:
+ document[SVG_G_STROKE] = "stroke = \"red\"";
+ break;
+ }
+}
+
+
+}
+}
+
+#endif

Added: sandbox/SOC/2007/visualization/boost/svg_plot/svg_instruction.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_instruction.hpp 2007-05-28 20:19:41 EDT (Mon, 28 May 2007)
@@ -0,0 +1,119 @@
+// svg_instruction.hpp
+
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// -----------------------------------------------------------------
+
+#ifndef _SVG_INSTRUCTION_HPP
+#define _SVG_INSTRUCTION_HPP
+
+namespace boost {
+namespace svg {
+
+enum instruction_type{SVG_POINT, SVG_WRITE, SVG_SIZE};
+enum svg_color{BLACK, GRAY, RED};
+
+// -----------------------------------------------------------------
+// The svg_instruction struct is what we are using to pass the svg
+// class arguments through the << operator interface.
+// -----------------------------------------------------------------
+struct svg_instruction
+{
+ instruction_type i_type;
+
+ svg_instruction(instruction_type i):i_type(i)
+ {
+ }
+};
+
+struct svg_point
+{
+ double x, y;
+
+ instruction_type i_type;
+
+ svg_point(double _x, double _y, instruction_type _it): x(_x), y(_y), i_type(_it)
+ {
+
+ }
+};
+
+struct svg_line
+{
+ double x1, y1, x2, y2;
+
+ svg_line(double _x1, double _y1, double _x2, double _y2):
+ x1(_x1), x2(_x2), y1(_y1), y2(_y2)
+ {
+
+ }
+};
+
+struct svg_text
+{
+ double x, y;
+ std::string text;
+
+ svg_text(double _x, double _y, std::string _t):x(_x), y(_y), text(_t)
+ {
+
+ }
+};
+
+struct svg_line_color
+{
+ svg_color col;
+
+ svg_line_color(svg_color _c):col(_c)
+ {
+
+ }
+};
+
+// -----------------------------------------------------------------
+// This allows the user to set the size of the image in centimeters
+// TODO: allow other unit identifiers
+// -----------------------------------------------------------------
+svg_point image_size(unsigned int width, unsigned int height)
+{
+ if(height<=0 || width<=0)
+ throw "Invalid image size";
+
+ return svg_point(width, height, SVG_SIZE);
+}
+
+svg_instruction write()
+{
+ return svg_instruction(SVG_WRITE);
+}
+
+svg_point draw_point(double x, double y)
+{
+ return svg_point(x, y, SVG_POINT);
+}
+
+svg_line draw_line(double x1, double y1, double x2, double y2)
+{
+ svg_line to_ret(x1, y1, x2, y2);
+
+ return to_ret;
+}
+
+svg_text draw_text(double x, double y,
+ const std::string& text)
+{
+ return svg_text(x, y, text);
+}
+
+svg_line_color line_color(svg_color c)
+{
+ return svg_line_color(c);
+}
+
+}
+}
+
+#endif

Added: sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp 2007-05-28 20:19:41 EDT (Mon, 28 May 2007)
@@ -0,0 +1,302 @@
+// svg_plot.hpp
+
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// -----------------------------------------------------------------
+
+#ifndef _SVG_PLOT_HPP
+#define _SVG_PLOT_HPP
+
+
+#include <vector>
+#include <ostream>
+#include <sstream>
+#include <iterator>
+#include <limits>
+
+#include "svg_plot_instruction.hpp"
+#include "svg.hpp"
+
+namespace boost {
+namespace svg {
+
+class svg_plot: public svg
+{
+private:
+ double transform_matrix[3][3];
+ double plot_start, plot_interval;
+
+ double x_min, x_max, y_min, y_max;
+
+ //Don't let the user use this without specifying a stream.
+ //I can't think of a reasonable default, and I don't think
+ //they'd want the svg formatted output spit to the console
+ svg_plot();
+
+ void _x_scale(double, double);
+ void _y_scale(double, double);
+ void _plot_image_size(unsigned int, unsigned int);
+ void _set_start(double);
+ void _set_interval(double);
+ void _plot_range(std::vector<double>::iterator,
+ std::vector<double>::iterator);
+
+ void _transform_point(double &x, double &y);
+ void _draw_axis();
+ void _set_stroke_color(svg_color);
+
+public:
+ using svg::operator<<;
+
+ svg_plot(const std::string& file);
+ void operator<<(const plot_single_val&);
+ void operator<<(const plot_scale&);
+ void operator<<(const plot_draw_range&);
+ void operator<<(const plot_command&);
+};
+
+// -----------------------------------------------------------------
+// Constructors will be added so that the user can specify
+// a stream instead of a filename
+//
+// This performs work for default values so that if the user starts
+// adding data right away, we won't get abnormal results
+// -----------------------------------------------------------------
+svg_plot::svg_plot(const std::string& file):svg(file)
+{
+ for(int i=0; i<3; ++i)
+ for(int j=0; j<3; ++j)
+ transform_matrix[i][j] = 0;
+
+ _size(100, 100);
+ x_min = y_min = 0;
+ x_max = y_max = 10;
+
+ transform_matrix[0][0] = transform_matrix[2][2] = transform_matrix[1][1] = 1;
+
+ transform_matrix[0][2] = x_size*(-x_min / (x_min - x_max));
+ transform_matrix[1][2] = y_size - y_size*(-y_min / (y_min - y_max));
+
+ //to determine: reasonable default values
+
+
+ plot_interval = 1;
+ plot_start = 1;
+}
+
+void svg_plot::operator<<(const plot_scale& rhs)
+{
+ switch(rhs.i_type)
+ {
+ case PLOT_SCALE_X:
+ _check_size();
+ _x_scale(rhs.x1, rhs.x2);
+ break;
+
+ case PLOT_SCALE_Y:
+ _check_size();
+ _y_scale(rhs.x1, rhs.x2);
+ break;
+
+ case PLOT_SIZE:
+ _plot_image_size((unsigned int)rhs.x1, (unsigned int)rhs.x2);
+ break;
+ }
+}
+
+void svg_plot::operator <<(const plot_single_val& rhs)
+{
+ switch(rhs.i_type)
+ {
+ case PLOT_INTERVAL:
+ _set_interval(rhs.x);
+ break;
+
+ case PLOT_START:
+ _set_start(rhs.x);
+ break;
+ }
+}
+
+void svg_plot::operator<<(const plot_command& rhs)
+{
+ _draw_axis();
+}
+
+void svg_plot::operator<<(const plot_draw_range& rhs)
+{
+ _plot_range(rhs.begin, rhs.end);
+}
+
+void svg_plot::_x_scale(double x1, double x2)
+{
+ x_min = x1;
+ x_max = x2;
+
+ if(x2 <= x1)
+ throw "Illegal Argument: X scale: x2 < x1";
+
+ transform_matrix[0][0] = x_size/(x2-x1);
+ transform_matrix[0][2] = x_size*(-x1 / (x2 - x1));
+}
+
+void svg_plot::_y_scale(double y1, double y2)
+{
+ y_min = y1;
+ y_max = y2;
+
+ if(y2 <= y1)
+ throw "Illegal Argument: Y scale: y2 < y1";
+
+ transform_matrix[1][1] = -1. * y_size/(y2-y1);
+ transform_matrix[1][2] = y_size - y_size*(-y1 / (y2 - y1));
+}
+
+void svg_plot::_plot_image_size(unsigned int x, unsigned int y)
+{
+ _size(x, y);
+
+ transform_matrix[0][2] = x_size*(-x_min / (x_min - x_max));
+ transform_matrix[1][2] = y_size - y_size*(-y_min / (y_min - y_max));
+}
+
+// -----------------------------------------------------------------
+// The user needs to set the start value in order for the first
+// point of the plot to render in the right place
+// -----------------------------------------------------------------
+void svg_plot::_set_start(double x)
+{
+ plot_start = x;
+}
+
+// -----------------------------------------------------------------
+// The user needs to set the interval to make each subsequent
+// node of the plot render in the right place
+// -----------------------------------------------------------------
+void svg_plot::_set_interval(double x)
+{
+ plot_interval = x;
+}
+
+void svg_plot::_plot_range(std::vector<double>::iterator begin,
+ std::vector<double>::iterator end)
+{
+ double x, y, x2, y2;
+
+ double i=0;
+
+ if(begin+1 == end)
+ {
+ x = plot_start;
+ y = *begin;
+
+ _transform_point(x, y);
+
+ _point(x, y);
+ }
+ else
+ {
+ for(std::vector<double>::iterator b = begin; b+1!=end; ++b)
+ {
+ x = plot_start+i;
+ y = *b;
+
+ x2 = plot_start+(i+1);
+ y2 = *(b+1);
+
+ _transform_point(x, y);
+ _transform_point(x2, y2);
+
+ _line(x, y, x2, y2);
+
+ i+=plot_interval;
+ }
+
+ i=0;
+
+ for(std::vector<double>::iterator b = begin; b!=end; ++b)
+ {
+ x = plot_start+i;
+ y = *b;
+
+ _transform_point(x, y);
+ _point(x, y);
+ i+=plot_interval;
+ }
+ }
+}
+
+// -----------------------------------------------------------------
+// This transforms a Cartesian point into a svg point. We don't
+// use the svg coordinate transform because sizing is a harder
+// problem in the svg coordinate transforms, and text would be
+// flipped if were were to mimic the Cartesian system
+// -----------------------------------------------------------------
+void svg_plot::_transform_point(double &x, double &y)
+{
+ x = transform_matrix[0][0]*x+transform_matrix[0][2];
+ y = (transform_matrix[1][1]*y+transform_matrix[1][2]);
+}
+
+
+// -----------------------------------------------------------------
+// TODO: Refactor
+// -----------------------------------------------------------------
+void svg_plot::_draw_axis()
+{
+ //two major axes
+ double x1,y1,x2,y2;
+
+ x1 = x2 = 0;
+ y1 = y_min;
+ y2 = y_max;
+
+ _transform_point(x1,y1);
+ _transform_point(x2,y2);
+
+ _line(x1, y1, x2, y2);
+
+ y1 = y2 = 0;
+ x1 = x_min;
+ x2 = x_max;
+
+ _transform_point(x1,y1);
+ _transform_point(x2,y2);
+
+ _line(x1, y1, x2, y2);
+
+ for(double i=x_min; i<=x_max; i+=plot_interval)
+ {
+ y1 = .2;
+ y2 = -.2;
+
+ x1=x2=i;
+
+ _transform_point(x1,y1);
+ _transform_point(x2,y2);
+
+ _line(x1,y1,x2,y2);
+ }
+
+ for(double i=y_min; i<=y_max; i+=plot_interval)
+ {
+ x1 = .2;
+ x2 = -.2;
+
+ y1=y2=i;
+
+ _transform_point(x1,y1);
+ _transform_point(x2,y2);
+
+ _line(x1,y1,x2,y2);
+ }
+}
+
+}
+}
+
+#endif
+

Added: sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot_instruction.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot_instruction.hpp 2007-05-28 20:19:41 EDT (Mon, 28 May 2007)
@@ -0,0 +1,108 @@
+// svg_plot_instruction.hpp
+
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// -----------------------------------------------------------------
+
+#ifndef _SVG_PLOT_INSTRUCTION_HPP
+#define _SVG_PLOT_INSTRUCTION_HPP
+
+#include <iterator>
+
+namespace boost {
+namespace svg {
+
+
+enum plot_inst_type{PLOT_SCALE_X, PLOT_SCALE_Y, PLOT_START, PLOT_SIZE,
+ PLOT_INTERVAL, PLOT_DRAW_AXIS};
+
+struct plot_command
+{
+ plot_inst_type i_type;
+
+ plot_command(plot_inst_type _i): i_type(_i)
+ {
+
+ }
+};
+
+struct plot_single_val
+{
+ double x;
+
+ plot_inst_type i_type;
+
+ plot_single_val(double _x, plot_inst_type _i): x(_x), i_type(_i)
+ {
+ }
+};
+
+struct plot_scale
+{
+ double x1, x2;
+
+ plot_inst_type i_type;
+
+ plot_scale(double _x1, double _x2, plot_inst_type _i)
+ :x1(_x1), x2(_x2), i_type(_i)
+ {
+
+ }
+};
+
+struct plot_draw_range
+{
+ std::vector<double>::iterator begin;
+ std::vector<double>::iterator end;
+
+ plot_draw_range(std::vector<double>::iterator _b,
+ std::vector<double>::iterator _e)
+ {
+ begin = _b;
+ end = _e;
+ }
+};
+
+
+plot_scale x_scale(double x1, double x2)
+{
+ return plot_scale(x1, x2, PLOT_SCALE_X);
+}
+
+plot_scale y_scale(double y1, double y2)
+{
+ return plot_scale(y1, y2, PLOT_SCALE_Y);
+}
+
+plot_scale image_size(int x, int y)
+{
+ return plot_scale(x, y, PLOT_SIZE);
+}
+
+plot_single_val set_start(double x)
+{
+ return plot_single_val(x, PLOT_START);
+}
+
+plot_single_val set_interval(double x)
+{
+ return plot_single_val(x, PLOT_INTERVAL);
+}
+
+plot_draw_range plot_range(std::vector<double>::iterator begin,
+ std::vector<double>::iterator end)
+{
+ return plot_draw_range(begin, end);
+}
+
+plot_command draw_axis()
+{
+ return plot_command(PLOT_DRAW_AXIS);
+}
+
+}
+}
+#endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk