1 /* 2 * arrow_data.cc -- ePiX arrow class 3 * 4 * This file is part of ePiX, a C++ library for creating high-quality 5 * figures in LaTeX 6 * 7 * Version 1.2.0-2 8 * Last Change: September 26, 2007 9 */ 10 11 /* 12 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 13 * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> 14 * Department of Mathematics and Computer Science 15 * College of the Holy Cross 16 * Worcester, MA, 01610-2395, USA 17 */ 18 19 /* 20 * ePiX is free software; you can redistribute it and/or modify it 21 * under the terms of the GNU General Public License as published by 22 * the Free Software Foundation; either version 2 of the License, or 23 * (at your option) any later version. 24 * 25 * ePiX is distributed in the hope that it will be useful, but WITHOUT 26 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 27 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 28 * License for more details. 29 * 30 * You should have received a copy of the GNU General Public License 31 * along with ePiX; if not, write to the Free Software Foundation, Inc., 32 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 33 */ 34 35 #include <list> 36 #include <cmath> 37 38 #include "triples.h" 39 #include "functions.h" 40 41 #include "camera.h" 42 43 #include "edge_data.h" 44 #include "path_data.h" 45 #include "clipping.h" 46 47 #include "arrow_style.h" 48 #include "pen_data.h" 49 #include "paint_style.h" 50 51 #include "halfspace.h" 52 #include "pen_line.h" 53 #include "pen_arrow.h" 54 55 #include "screen_data.h" 56 #include "screen.h" 57 #include "active_screen.h" 58 59 #include "arrow_data.h" 60 61 namespace ePiX { 62 arrow_data(const std::vector<P> & pv,const P & base,const P & tip,double scale)63 arrow_data::arrow_data(const std::vector<P>& pv, const P& base, const P& tip, 64 double scale) 65 : m_base(base), m_tip(tip), m_scale(scale), 66 m_head_seen(!the_clip_box().clips(m_tip)) 67 { 68 for (unsigned int i=0; i<pv.size()-1; ++i) 69 m_shaft.push_back(edge3d(pv.at(i), pv.at(i+1), true)); 70 71 the_clip_box().clip_path(m_shaft); 72 } 73 clip_to(const halfspace & knife)74 arrow_data& arrow_data::clip_to(const halfspace& knife) 75 { 76 knife.clip_path(m_shaft); 77 if (knife.clips(m_tip)) 78 m_head_seen = false; 79 80 return *this; 81 } 82 83 photo(screen & scr,const Camera & mycam,const pen_data & line,const pen_data & under) const84 void arrow_data::photo(screen& scr, const Camera& mycam, 85 const pen_data& line, const pen_data& under) const 86 { 87 arrow_data tmp_data(*this); 88 if (mycam.needs_clip()) 89 tmp_data.clip_to(mycam.clip_plane()); 90 91 std::list<edge2d> edges; 92 for (std::list<edge3d>::const_iterator p=tmp_data.m_shaft.begin(); 93 p != tmp_data.m_shaft.end(); ++p) 94 { 95 edge2d tmp(mycam((*p).tail()), mycam((*p).head()), (*p).is_seen()); 96 97 if (!tmp.is_null()) // endpoints not equal 98 edges.push_back(tmp); 99 } 100 101 // draw shaft 102 scr.m_screen->add_tile(pen_line(line.seen_through(mycam), 103 under.seen_through(mycam), edges)); 104 105 // and arrowhead 106 if (m_head_seen) 107 { 108 const P dir(m_tip-m_base); 109 const P to_cam(mycam.viewpt()-m_base); 110 111 const double sin_th(norm(dir*to_cam)/(norm(dir)*norm(to_cam))); 112 113 scr.m_screen->add_tile(pen_arrow(mycam(m_base), mycam(m_tip), 114 line.seen_through(mycam), 115 under.seen_through(mycam), 116 m_scale, sin_th, m_head_seen)); 117 } 118 } 119 draw() const120 void arrow_data::draw() const 121 { 122 photo(*active_screen(), cam(), 123 the_paint_style().line_pen(), the_paint_style().base_pen()); 124 } 125 draw(const pen_data & p1,const pen_data & p2) const126 void arrow_data::draw(const pen_data& p1, const pen_data& p2) const 127 { 128 photo(*active_screen(), cam(), p1, p2); 129 } 130 } // end of namespace 131