/* * facet.cc -- Utility classes for shaded surface plotting * * This file is part of ePiX, a C++ library for creating high-quality * figures in LaTeX * * Version 1.2.0-2 * Last Change: September 26, 2007 */ /* * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 * Andrew D. Hwang * Department of Mathematics and Computer Science * College of the Holy Cross * Worcester, MA, 01610-2395, USA */ /* * ePiX is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * ePiX 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 General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with ePiX; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "constants.h" #include "errors.h" #include "functions.h" #include "frame.h" #include "camera.h" #include "Color.h" #include "paint_style.h" #include "facet.h" namespace ePiX { facet::facet(P f(double, double), double u0, double v0, double du, double dv, const unsigned int N1, const unsigned int N2) : m_tint(the_paint_style().fill_color()), m_line(the_paint_style().line_pen()), m_fill(the_paint_style().fill_flag()), pt1(f(u0, v0)), pt2(f(u0 + N1*du, v0)), pt3(f(u0 + N1*du, v0 + N2*dv)), pt4(f(u0, v0 + N2*dv)), center(0.25*(pt1 + pt2 + pt3 + pt4)), direction(center-cam().viewpt()), distance(norm(direction)) { perp = ((pt2 - center)*(pt1 - center)); if (norm(perp) < EPIX_EPSILON) perp = (pt4 - center)*(pt3 - center); perp *= recip(norm(perp)); // bottom edge for (unsigned int i=0; i -EPIX_EPSILON; } // N.B. We assume the fill state is stored by our caller void facet::draw(int cull) const { if (( cull == 1 && front_facing() ) || ( cull == -1 && !front_facing() )) return; // else Color paint(m_tint); if (paint.is_unset()) paint = White(); Color ink(m_line.color()); if (ink.is_unset()) ink = paint; if (m_fill) { // calculate cosine^2 of normal angle // Magic formula (simulated ambient lighting) const double dens(0.5*(1+pow(perp|(recip(distance)*direction), 2))); paint *= dens; ink *= dens; } bd.draw(paint, pen_data(ink, m_line.width())); } // end of facet::draw(bool, int) bool by_distance::operator() (const facet& arg1, const facet& arg2) { return arg1.how_far() > arg2.how_far(); } bool by_distance::operator() (const facet* arg1, const facet* arg2) { return arg1->how_far() > arg2->how_far(); } } // end of namespace