GTK+ IOStream  Beta
<< GTK+ >> add C++ IOStream operators to GTK+. Now with extra abilities ... like network serialisation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CairoArrow.H
Go to the documentation of this file.
1 /* Copyright 2000-2013 Matt Flax <flatmax@flatmax.org>
2 /* Copyright 2000-2013 Matt Flax <flatmax@flatmax.org>
3  This file is part of GTK+ IOStream class set
4 
5  GTK+ IOStream is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  GTK+ IOStream is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You have received a copy of the GNU General Public License
16  along with GTK+ IOStream
17  */
18 
19 #ifndef CAIROARROW_H_
20 #define CAIROARROW_H_
21 
22 #include <math.h>
23 #include <cairo/cairo.h>
24 
30 class CairoArrow {
31  float xSide1, xSide2;
32  float ySide1, ySide2;
33  float vecX, vecY;
34 
45  void findArrowHeadPoints(float xBase, float yBase, float xPoint, float yPoint, float headToLengthRatio, float width){
46  vecX=xPoint-xBase, vecY=yPoint-yBase; // the vector form the base to the point translated to the origin.
47  float shaftLength=sqrt(powf(vecX,2.)+powf(vecY,2.));
48  float theta=2*M_PI*.25; // Find the orthogonal unit vector
49  float cosTheta=cos(theta), sinTheta=sin(theta);
50  float unitX=vecX/shaftLength, unitY=vecY/shaftLength;
51  float rotX=unitX*cosTheta-unitY*sinTheta, rotY=unitX*sinTheta+unitY*cosTheta;
52  float orthX=rotX*width, orthY=rotY*width;
53  xSide1=xPoint-vecX*headToLengthRatio+orthX; // find the arrow head side points based on the orthogonal unit vector to the shaft
54  xSide2=xPoint-vecX*headToLengthRatio-orthX;
55  ySide1=yPoint-vecY*headToLengthRatio+orthY;
56  ySide2=yPoint-vecY*headToLengthRatio-orthY;
57  }
58 
59 public:
68  CairoArrow(void) {
69  }
70 
87  CairoArrow(cairo_t *cr, float xBase, float yBase, float xPoint, float yPoint, float headToLengthRatio, float width, bool closed, bool filled) {
88  draw(cr, xBase, yBase, xPoint, yPoint, headToLengthRatio, width, closed, filled);
89  }
90 
103  void draw(cairo_t *cr, float xBase, float yBase, float xPoint, float yPoint, float headToLengthRatio, float width, bool closed, bool filled) {
104  findArrowHeadPoints(xBase, yBase, xPoint, yPoint, headToLengthRatio, width);
105  cairo_move_to (cr, xBase, yBase); // start at the base and draw the shaft
106  float scale=0.;
107  if (closed|filled) // if closed, then just draw up to the arrow head
108  scale=headToLengthRatio;
109  cairo_line_to (cr, xBase+vecX*(1-scale), yBase+vecY*(1-scale));
110  cairo_stroke (cr);
111  // now draw the arrow head
112  if (filled || closed) // close the path if filled or closed
113  cairo_new_sub_path (cr);
114  cairo_move_to (cr, xSide1, ySide1); // start at side1 and draw to the point, then side2
115  cairo_line_to (cr, xPoint, yPoint);
116  cairo_line_to (cr, xSide2, ySide2);
117  if (filled || closed) // close the path if filled or closed
118  cairo_close_path(cr);
119  if (!filled)
120  cairo_stroke (cr);
121  else
122  cairo_fill (cr);
123  }
124 
125  virtual ~CairoArrow() {
126  }
127 };
128 
129 #endif // CAIROARROW_H_