File: main.cpp

package info (click to toggle)
libclaw 1.7.4-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,080 kB
  • sloc: cpp: 13,287; sh: 227; makefile: 8
file content (151 lines) | stat: -rw-r--r-- 4,616 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
  CLAW - a C++ Library Absolutely Wonderful

  CLAW is a free library without any particular aim but being useful to 
  anyone.

  Copyright (C) 2005-2011 Julien Jorge

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  contact: julien.jorge@gamned.org
*/
/**
 * \file
 * \brief Example program for the Bzier curves of Claw.
 * \author Julien Jorge
 */

#include <claw/curve.hpp>

#include <claw/png.hpp>
#include <claw/string_algorithm.hpp>

#include <fstream>
#include <iostream>

typedef claw::math::coordinate_2d<double> coordinate_type;
typedef claw::math::curve<coordinate_type> curve_type;

/**
 * \brief Read the points of a curve from a stream.
 * 
 * The stream must describe the points in the following format:
 * x y in_x in_y out_x out_y
 *
 * Where (x, y) is the coordinate of the control point, (in_x, in_y) is the
 * coordinate of the direction of the curve when entering the point and
 * (out_x, out_y) is the direction of the curve when leaving the point.
 *
 * If the in and out points are not set, they are set to (x, y) by default.
 *
 * \param c The curve to which the points are added.
 * \param is The stream from which the curve is read.
 */
claw::math::coordinate_2d<std::size_t>
read_curve( curve_type& c, std::istream& is )
{
  claw::math::coordinate_2d<std::size_t> max(0, 0);

  std::string line;

  while ( claw::text::getline( is, line ) )
    {
      std::istringstream iss(line);
      coordinate_type position;

      if ( iss >> position.x >> position.y )
        {
          max.x = std::max( (std::size_t)position.x, max.x );
          max.y = std::max( (std::size_t)position.y, max.y );

          coordinate_type in, out;

          if ( iss >> in.x >> in.y >> out.x >> out.y )
            c.push_back( curve_type::control_point(position, in, out) );
          else
            c.push_back( curve_type::control_point(position) );
        }
    }

  return max;
} // read_curve()

/**
 * \brief Draw the curve with a given precision.
 * \param result The image in which the curve is drawn.
 * \param c The curve to draw.
 * \param step The step between two points of the curve.
 */
void draw_curve
( claw::graphic::image& result, const curve_type& c, double step )
{
  for ( curve_type::const_iterator it=c.begin(); it!=c.end(); ++it )
    {
      const curve_type::section s( c.get_section(it) );

      for ( double t(0); t<=1; t+=step )
        {
          const claw::math::coordinate_2d<int> p( s.get_point_at(t) );

          if ( ( (0 <= p.x) && (p.x < (int)result.width()) )
               && ( (0 <= p.y) && (p.y < (int)result.height()) ) )
            result[ p.y ][ p.x ] = claw::graphic::black_pixel;
        }
    }
} // draw_curve()

/**
 * \brief Draw a curve in an image.
 */
int main( int argc, char* argv[] )
{
  if ( argc != 2 )
    {
      std::cerr << "usage:\n"
                << '\t' << argv[0] << " step\n\n"
                << "The program reads the coordinates of the curve on stdin.\n"
                << "Each line represents a point in the following format:\n"
                << "\tx y input_x input_y output_x output_y\n"
                << "The curve is drawn in an image saved as output.png with a"
                << " detail of step.\n\n"
                << "example:\n"
                << "\tcat example | " << argv[0] << "0.001\n\n"
                << "where the content of example is:\n"
                << "0 0 0 0 75 25\n"
                << "50 75 75 75 25 75\n"
                << "100 0 25 25 100 0";
      std::cerr << std::endl;
      return 1;
    }

  double step(1);
  std::istringstream iss(argv[1]);

  iss >> step;

  curve_type c;

  claw::math::coordinate_2d<std::size_t> bounds = read_curve( c, std::cin );
  claw::graphic::png result( bounds.x, bounds.y );

  std::fill( result.begin(), result.end(), claw::graphic::white_pixel );

  draw_curve( result, c, step );

  std::ofstream f("output.png");
  result.save( f );

  return 0;
} // main()