1 /**
2 * @file tilings.cpp
3 * @author Sebastien Fourey (GREYC)
4 *
5 * @brief Sample program that draws a ruler.
6 *
7 * This source code is part of the Board project, a C++ library whose
8 * purpose is to allow simple drawings in EPS, FIG or SVG files.
9 * Copyright (C) 2007 Sebastien Fourey <http://foureys.users.greyc.fr>
10 */
11 #include "Board.h"
12 #include <cstdlib>
13 #include <cmath>
14 #include <limits>
15 #include <vector>
16 #include <cassert>
17 using namespace LibBoard;
18
19 #include <board/PathBoundaries.h>
20
strikeOut(const Path & path,double strokeWidth,Shape::LineCap lineCap,Shape::LineJoin lineJoin,double miterLimit=4.0)21 ShapeList strikeOut( const Path & path,
22 double strokeWidth,
23 Shape::LineCap lineCap,
24 Shape::LineJoin lineJoin,
25 double miterLimit = 4.0 )
26 {
27 const double s = 1.0;
28 ShapeList list;
29 std::vector<Point> e = Tools::pathBoundaryPoints(path,strokeWidth,lineCap, lineJoin, miterLimit );
30 size_t limit = (path.closed()?path.size():(path.size()-1));
31 for ( size_t i = 0; i < limit; ++i ) {
32 Point a = path[i];
33 Point b = path[(i+1)%path.size()];
34 Point v = b-a;
35 Point shift = 0.5 * strokeWidth * v.rotatedPI2().normalise();
36 list << Line(a+shift,b+shift,Color::Black,strokeWidth*0.01).scale(s);
37 list << Line(a-shift,b-shift,Color::Black,strokeWidth*0.01).scale(s);
38 list << Line(a,b,Color::Red,strokeWidth*0.01);
39 if ( (lineCap == Shape::RoundCap) || (lineJoin == Shape::RoundJoin)) {
40 list << Circle(a,strokeWidth*0.5,Color::Green,Color::Null,strokeWidth*0.01);
41 }
42 }
43 if ( (!path.closed() && lineCap == Shape::RoundCap) || (lineJoin == Shape::RoundJoin) ) {
44 Point a = path[path.size()-1];
45 list << Circle(a,strokeWidth*0.5,Color::Green,Color::Null,strokeWidth*0.01);
46 }
47
48 for ( size_t i = 0; i < e.size(); ++i ) {
49 Point c = e[i];
50 list << Circle(c,10.0,Color::Blue,Color::Null,strokeWidth*0.01);
51 list << Line(c-Point(10.0,0.0), c+Point(10.0,0),Color::Blue,strokeWidth*0.01);
52 list << Line(c-Point(0.0,10.0), c+Point(0,10.0),Color::Blue,strokeWidth*0.01);
53 }
54 return list;
55 }
56
main(int,char * [])57 int main( int , char *[] )
58 {
59 Board board;
60 Shape::enableLineWidthScaling();
61 board.clear( Color::White);
62
63 // http://www.w3.org/TR/SVG/painting.html#StrokeProperties
64
65 Point p1(30,366);
66 Point p2(200,400);
67 Point p3(0,0);
68 Point p4(-100,20);
69 Point p5(-50,-100);
70
71 Path pA(true);
72 pA<<p1<<p2<<p3<<p4<<p5;
73 Path pB(true);
74 pB<<Point(0,0)<<Point(180,0)<<Point(180,300)<<Point(0,300);
75 Path pC(true);
76 pC << Point(0,0) << Point(200,0) << Point(500,5) << Point(150,200);
77
78 Path losange;
79 losange << Point(0,0) << Point(300,-500) << Point(600,0) << Point(300,500);
80
81 ShapeList l;
82 l.append( strikeOut(pA,50.0,Shape::RoundCap,Shape::MiterJoin, 3.0 ),
83 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
84 l.append( strikeOut(pB,50.0,Shape::RoundCap,Shape::BevelJoin, 3.0 ),
85 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
86 l.append( strikeOut(pC,50.0,Shape::RoundCap,Shape::MiterJoin, 3.0 ),
87 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
88 l.append( strikeOut(pA,50.0,Shape::RoundCap,Shape::RoundJoin, 3.0 ),
89 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
90 l.append(Text(0,0,"Round cap, miter/bevel/miter/round join",Fonts::Courier,14.0),ShapeList::Right,ShapeList::AlignCenter);
91 board.append(l,ShapeList::Bottom,ShapeList::AlignLeft);
92
93 l.clear();
94 l.append( strikeOut(pA,50.0,Shape::ButtCap,Shape::MiterJoin, 3.0 ),
95 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
96 l.append( strikeOut(pB,50.0,Shape::ButtCap,Shape::BevelJoin, 3.0 ),
97 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
98 l.append( strikeOut(pC,50.0,Shape::ButtCap,Shape::MiterJoin, 3.0 ),
99 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
100 l.append( strikeOut(pA,50.0,Shape::ButtCap,Shape::RoundJoin, 3.0 ),
101 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
102 l.append(Text(0,0,"Butt cap, miter/bevel/miter/round join",Fonts::Courier,14.0),ShapeList::Right,ShapeList::AlignCenter);
103 board.append(l,ShapeList::Bottom,ShapeList::AlignLeft);
104
105 l.clear();
106 l.append( strikeOut(pA,50.0,Shape::SquareCap,Shape::MiterJoin, 3.0 ),
107 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
108 l.append( strikeOut(pB,50.0,Shape::SquareCap,Shape::BevelJoin, 3.0 ),
109 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
110 l.append( strikeOut(pC,50.0,Shape::SquareCap,Shape::MiterJoin, 3.0 ),
111 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
112 l.append( strikeOut(pA,50.0,Shape::SquareCap,Shape::RoundJoin, 3.0 ),
113 ShapeList::Right, ShapeList::AlignCenter, 30.0 );
114 l.append(Text(0,0,"Square cap, miter/bevel/miter/round join",Fonts::Courier,14.0),ShapeList::Right,ShapeList::AlignCenter);
115 board.append(l,ShapeList::Bottom,ShapeList::AlignLeft);
116
117 ShapeList list;
118 Polyline poly(true,Color::Blue,Color::Null,1.0,Shape::SolidStyle,Shape::ButtCap,Shape::MiterJoin);
119 poly << Point(0,0) << Point(30,-50) << Point(60,0) << Point(30,50);
120 list.append(poly,ShapeList::Right,ShapeList::AlignCenter);
121 list.append(poly,ShapeList::Right,ShapeList::AlignCenter);
122 board.append(list,ShapeList::Right,ShapeList::AlignCenter);
123 board.append( Rectangle(0,0,100,30).rotateDeg(40).scale(1.5,1.0),
124 ShapeList::Right,ShapeList::AlignCenter);
125
126 board.saveEPS( "stroke_path.eps" , Board::A4 );
127
128 board.scaleToWidth(25,Board::UseLineWidth);
129 board.saveSVG( "stroke_path.svg", Board::BoundingBox, 0.0, Board::UCentimeter );
130 }
131