$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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