1 /* 2 * Sline.cc -- ePiX::Sline class (spherical arc) 3 * 4 * This file is part of ePiX, a preprocessor for creating high-quality 5 * line figures in LaTeX 6 * 7 * Version 1.2.17 8 * Last Change: June 30, 2017 9 */ 10 11 /* 12 * Copyright (C) 2017 13 * Andrew D. Hwang <rot 13 nujnat at 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 <cmath> 36 #include "constants.h" 37 #include "errors.h" 38 39 #include "triples.h" 40 #include "geometry.h" 41 42 #include "Sline.h" 43 44 namespace ePiX { Sline(const P & tail,const P & head)45 Sline::Sline(const P& tail, const P& head) 46 : m_tail(tail), m_head(head), m_malformed(false) 47 { 48 double mt(norm(tail)), mh(norm(head)); 49 if (fabs(mt - 1) > EPIX_EPSILON) 50 { 51 epix_warning("First argument of Sline is not a unit vector"); 52 if (EPIX_EPSILON < mt && mt < EPIX_INFTY) 53 m_tail *= 1.0/mt; 54 else 55 m_malformed = true; 56 } 57 58 if (fabs(mh - 1) > EPIX_EPSILON) 59 { 60 epix_warning("Second argument of Sline is not a unit vector"); 61 if (EPIX_EPSILON < mh && mh < EPIX_INFTY) 62 m_head *= 1.0/mh; 63 else 64 m_malformed = true; 65 } 66 67 m_pole = m_tail * m_head; 68 double mp(norm(m_pole)); 69 if (mp < EPIX_EPSILON) 70 { 71 epix_warning("Collinear arguments in Sline"); 72 m_pole = P(0,0,0); 73 m_malformed = true; 74 } 75 76 else // well-formed; normalize pole 77 m_pole *= 1.0/mp; 78 } // end of Sline::Sline 79 malformed() const80 bool Sline::malformed() const 81 { 82 return m_malformed; 83 } 84 pole() const85 P Sline::pole() const 86 { 87 if (m_malformed) 88 epix_warning("Pole of malformed Sline requested"); 89 90 return m_pole; 91 } 92 cosine() const93 double Sline::cosine() const 94 { 95 return (m_tail | m_head); 96 } 97 operator *(const Sline & arg) const98 P Sline::operator * (const Sline& arg) const 99 { 100 if (m_malformed || arg.m_malformed) 101 { 102 epix_warning("Malformed argument(s) in Sline intersection"); 103 return P(0,0,0); 104 } 105 else if (this -> collinear(arg)) 106 { 107 epix_warning("Collinear argument(s) in Sline intersection"); 108 return P(0,0,0); 109 } 110 111 // else 112 P val(m_pole * arg.m_pole); 113 val *= 1.0/norm(val); 114 115 if (0 < (m_tail | val)) 116 return val; 117 118 else 119 return -val; 120 } 121 reflect(const P & arg) const122 P Sline::reflect(const P& arg) const 123 { 124 return arg - 2*(m_pole | arg)*m_pole; 125 } 126 reflect(const Sline & arg) const127 Sline Sline::reflect(const Sline& arg) const 128 { 129 return Sline(this -> reflect(arg.m_tail), this -> reflect(arg.m_head)); 130 } 131 collinear(const Sline & arg) const132 bool Sline::collinear(const Sline& arg) const 133 { 134 return m_malformed || 135 arg.m_malformed || 136 norm(m_pole * arg.m_pole) < EPIX_EPSILON; 137 } 138 cuts(const Sline & arg) const139 bool Sline::cuts(const Sline& arg) const // we and arg cross 140 { 141 return ((m_tail | arg.m_pole)*(m_head | arg.m_pole) < 0 && 142 (m_pole | arg.m_tail)*(m_pole | arg.m_head) < 0); 143 } 144 draw() const145 void Sline::draw() const 146 { 147 this -> draw_front(); 148 this -> draw_back(); 149 } 150 draw_front() const151 void Sline::draw_front() const // front arc 152 { 153 front_arc(m_tail, m_head); 154 } 155 draw_back() const156 void Sline::draw_back() const // back arc 157 { 158 back_arc(m_tail, m_head); 159 } 160 draw_line() const161 void Sline::draw_line() const 162 { 163 this -> line_back(); 164 this -> line_front(); 165 } 166 line_front() const167 void Sline::line_front() const 168 { 169 front_line(m_tail, m_head); 170 } 171 line_back() const172 void Sline::line_back() const // back line 173 { 174 back_line(m_tail, m_head); 175 } 176 } // end of namespace 177