/*
*
* This file is part of the Virtual Leaf.
*
* VirtualLeaf 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 3 of the License, or
* (at your option) any later version.
*
* VirtualLeaf 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 the Virtual Leaf. If not, see .
*
* Copyright 2010 Roeland Merks.
*
*/
#include
#include "wall.h"
#include "wallbase.h"
#include "node.h"
#include "mesh.h"
#include "parameter.h"
#include
#include
#include "warning.h"
#ifdef QTGRAPHICS
#include
#include
#include "wallitem.h"
//#include "apoplastitem.h"
#endif
static const std::string _module_id("$Id$");
int WallBase::nwalls=0;
ostream &WallBase::print(ostream &os) const {
os << "{ " << n1->Index() << "->" << n2->Index()
<< ", " << c1->Index() << " | " << c2->Index() << "} ";
return os;
}
ostream &operator<<(ostream &os, const WallBase &w) {
w.print(os);
return os;
}
WallBase::WallBase(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2)
{
#ifdef QDEBUG
if (sc1==sc2) {
qDebug() << "Attempting to build a wall between identical cells: " << sc1->Index() << endl;
}
#endif
c1 = sc1;
c2 = sc2;
n1 = sn1;
n2 = sn2;
transporters1 = new double[CellBase::NChem()];
transporters2 = new double[CellBase::NChem()];
new_transporters1 = new double[CellBase::NChem()];
new_transporters2 = new double[CellBase::NChem()];
for (int i=0;itransporters1[i];
src->transporters1[i]=transporters1[i];
transporters1[i]=tmp;
}
if (transporters2) {
double tmp;
tmp=src->transporters2[i];
src->transporters2[i]=transporters2[i];
transporters2[i]=tmp;
}
if (new_transporters1) {
double tmp;
tmp=src->new_transporters1[i];
src->new_transporters1[i]=new_transporters1[i];
new_transporters1[i]=tmp;
}
if (new_transporters2) {
double tmp;
tmp=src->new_transporters2[i];
src->new_transporters2[i]=new_transporters2[i];
new_transporters2[i]=tmp;
}
/* if (apoplast) {
double tmp;
tmp=src->apoplast[i];
src->apoplast[i]=apoplast[i];
apoplast[i]=tmp;
}*/
}
bool tmp_bool;
tmp_bool = src->dead;
src->dead=dead;
dead = tmp_bool;
WallType tmp_wall_type;
tmp_wall_type = src->wall_type;
src->wall_type = wall_type;
wall_type = tmp_wall_type;
}
bool WallBase::SAM_P(void)
{
return N1()->sam || N2()->sam;
}
#include
void WallBase::SetLength(void)
{
// Step 1: find the path of nodes leading along the WallBase.
// A WallBase often represents a curved cell wall: we want the total
// length _along_ the wall here...
// Locate first and second nodes of the edge in Cell's list of nodes
list::const_iterator first_node_edge = find(c1->nodes.begin(), c1->nodes.end(), n1);
list::const_iterator second_node_edge_plus_1 = ++find(c1->nodes.begin(), c1->nodes.end(), n2);
// wrap around
if (second_node_edge_plus_1 == c1->nodes.end()) {
second_node_edge_plus_1 = c1->nodes.begin();
}
length = 0.;
// Now, walk to the second node of the edge in the list of nodes
stringstream deb_str;
for (list::const_iterator n=
(++first_node_edge==c1->nodes.end()?c1->nodes.begin():first_node_edge);
n!=second_node_edge_plus_1;
(++n == c1->nodes.end()) ? (n=c1->nodes.begin()):n ) {
list::const_iterator prev_n = n;
if (prev_n==c1->nodes.begin()) prev_n=c1->nodes.end();
--prev_n;
//cerr << "Node: " << (Vector)(**n) << endl;
// Note that Node derives from a Vector, so we can do vector calculus as defined in vector.h
deb_str << "[ " << (*prev_n)->index << " to " << (*n)->index << "]";
length += (*(*prev_n) - *(*n)).Norm();
}
}
void WallBase::CorrectTransporters(double orig_length)
{
double length_factor = length / orig_length;
for (int ch=0;ch p2
bool WallBase::IntersectsWithDivisionPlaneP(const Vector &p1, const Vector &p2)
{
// Algorithm of http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
double x1 = n1->x, y1 = n1->y;
double x2 = n2->x, y2 = n2->y;
double x3 = p1.x, y3 = p1.y;
double x4 = p2.x, y4 = p2.y;
double ua = ( (x4 - x3) * (y1-y3) - (y4 - y3)*(x1-x3) ) / ( (y4 -y3) * (x2 -x1) - (x4-x3)*(y2-y1));
// If ua is between 0 and 1, line p1 intersects the line segment
if ( ua >=0. && ua <=1.) return true;
else return false;
}
/* finis */