示例#1
0
ExclusionPolygon::ExclusionPolygon(PassOwnPtr<Vector<FloatPoint> > vertices, WindRule fillRule)
    : ExclusionShape()
    , m_vertices(vertices)
    , m_fillRule(fillRule)
{
    unsigned nVertices = numberOfVertices();
    m_edges.resize(nVertices);
    m_empty = nVertices < 3;

    if (nVertices)
        m_boundingBox.setLocation(vertexAt(0));

    if (m_empty)
        return;

    unsigned minVertexIndex = 0;
    for (unsigned i = 1; i < nVertices; ++i) {
        const FloatPoint& vertex = vertexAt(i);
        if (vertex.y() < vertexAt(minVertexIndex).y() || (vertex.y() == vertexAt(minVertexIndex).y() && vertex.x() < vertexAt(minVertexIndex).x()))
            minVertexIndex = i;
    }
    FloatPoint nextVertex = vertexAt((minVertexIndex + 1) % nVertices);
    FloatPoint prevVertex = vertexAt((minVertexIndex + nVertices - 1) % nVertices);
    bool clockwise = determinant(vertexAt(minVertexIndex) - prevVertex, nextVertex - prevVertex) > 0;

    unsigned edgeIndex = 0;
    unsigned vertexIndex1 = 0;
    do {
        m_boundingBox.extend(vertexAt(vertexIndex1));
        unsigned vertexIndex2 = findNextEdgeVertexIndex(vertexIndex1, clockwise);
        m_edges[edgeIndex].polygon = this;
        m_edges[edgeIndex].vertexIndex1 = vertexIndex1;
        m_edges[edgeIndex].vertexIndex2 = vertexIndex2;
        m_edges[edgeIndex].edgeIndex = edgeIndex;
        edgeIndex++;
        vertexIndex1 = vertexIndex2;
    } while (vertexIndex1);

    if (edgeIndex > 3) {
        const ExclusionPolygonEdge& firstEdge = m_edges[0];
        const ExclusionPolygonEdge& lastEdge = m_edges[edgeIndex - 1];
        if (areCollinearPoints(lastEdge.vertex1(), lastEdge.vertex2(), firstEdge.vertex2())) {
            m_edges[0].vertexIndex1 = lastEdge.vertexIndex1;
            edgeIndex--;
        }
    }

    m_edges.resize(edgeIndex);
    m_empty = m_edges.size() < 3;

    if (m_empty)
        return;

    for (unsigned i = 0; i < m_edges.size(); i++) {
        ExclusionPolygonEdge* edge = &m_edges[i];
        m_edgeTree.add(EdgeInterval(edge->minY(), edge->maxY(), edge));
    }
}
示例#2
0
unsigned ExclusionPolygon::findNextEdgeVertexIndex(unsigned vertexIndex1, bool clockwise) const
{
    unsigned nVertices = numberOfVertices();
    unsigned vertexIndex2 = nextVertexIndex(vertexIndex1, nVertices, clockwise);

    while (vertexIndex2 && areCoincidentPoints(vertexAt(vertexIndex1), vertexAt(vertexIndex2)))
        vertexIndex2 = nextVertexIndex(vertexIndex2, nVertices, clockwise);

    while (vertexIndex2) {
        unsigned vertexIndex3 = nextVertexIndex(vertexIndex2, nVertices, clockwise);
        if (!areCollinearPoints(vertexAt(vertexIndex1), vertexAt(vertexIndex2), vertexAt(vertexIndex3)))
            break;
        vertexIndex2 = vertexIndex3;
    }

    return vertexIndex2;
}
示例#3
0
int CXXSurface::upLoadSphere(CXXSphereElement &theSphere, double probeRadius, const int sense){
    int oldVertexCount;
    CXXCoord theCentre = theSphere.centre();
    
    vector<int, CXX::CXXAlloc<int> > equivalence(theSphere.nVertices());
    vector<int, CXX::CXXAlloc<int> > uniqueAndDrawn(theSphere.nVertices());
    
    int nDrawn = 0;
    for (unsigned  i=0; i< theSphere.nVertices(); i++){
        CXXCoord comp1(theSphere.vertex(i).vertex());
        uniqueAndDrawn[i] = 0;
        if (theSphere.vertex(i).doDraw()){
            uniqueAndDrawn[i] = 1;
            if (uniqueAndDrawn[i]){
                equivalence[i] = nDrawn++;
            }
        }
    }
    static const std::string vertexName("vertices");
    static const std::string accessiblesName("accessibles");
    static const std::string normalsName("normals");
    {
        oldVertexCount = numberOfVertices();
        vertices.resize(oldVertexCount+nDrawn);
        int verticesHandle = getVectorHandle(vertexName);
        int accessiblesHandle = getVectorHandle(accessiblesName);
        int normalsHandle = getVectorHandle(normalsName);
        int iDraw = 0;
        for (unsigned int i=0; i< theSphere.nVertices(); i++){
            if (uniqueAndDrawn[i]){
                CXXCoord vertexCoord = theSphere.vertex(i).vertex();
                if (sense == CXXSphereElement::Contact){
                    vertices[oldVertexCount+iDraw].setCoord(accessiblesHandle, vertexCoord);
                    CXXCoord normal = vertexCoord - theCentre;
                    CXXCoord diff(normal);
                    diff *= (theSphere.radius() - probeRadius) / theSphere.radius();
                    normal.normalise();
                    vertices[oldVertexCount+iDraw].setCoord(normalsHandle, normal);
                    CXXCoord vertex = theCentre + diff;
                    vertices[oldVertexCount+iDraw].setCoord(verticesHandle, vertex);
                }
                else if (sense == CXXSphereElement::Reentrant) {
                    vertices[oldVertexCount+iDraw].setCoord(verticesHandle, vertexCoord);
                    CXXCoord normal = theCentre - vertexCoord;
                    normal.normalise();
                    vertices[oldVertexCount+iDraw].setCoord(normalsHandle, normal);
                    vertices[oldVertexCount+iDraw].setCoord(accessiblesHandle, theCentre);
                }
                else if (sense == CXXSphereElement::VDW) {
                    vertices[oldVertexCount+iDraw].setCoord(verticesHandle, vertexCoord);
                    CXXCoord normal = vertexCoord - theCentre;
                    normal.normalise();
                    vertices[oldVertexCount+iDraw].setCoord(normalsHandle, normal);
                    vertices[oldVertexCount+iDraw].setCoord(accessiblesHandle, vertexCoord+normal);
                }
                else if (sense == CXXSphereElement::Accessible) {
                    vertices[oldVertexCount+iDraw].setCoord(verticesHandle, vertexCoord);
                    CXXCoord normal = vertexCoord - theCentre;
                    normal.normalise();
                    vertices[oldVertexCount+iDraw].setCoord(normalsHandle, normal);
                    vertices[oldVertexCount+iDraw].setCoord(accessiblesHandle, vertexCoord);
                }
                iDraw++;
            }
        }
    }
    //Add atom pointers to the surface
    {
        void *atomBuffer[nDrawn];// = new void*[nDrawn];
        int iDraw = 0;
        for (unsigned int i=0; i< theSphere.nVertices(); i++){
            if (uniqueAndDrawn[i]){
                mmdb::PAtom anAtom;
                if ((anAtom = theSphere.vertex(i).getAtom())!=0 ){
                    atomBuffer[iDraw] = (void *) anAtom;
                }
                else atomBuffer[iDraw] = (void *) theSphere.getAtom();
                iDraw++;
            }
        }
        updateWithPointerData(nDrawn, "atom", oldVertexCount, atomBuffer);
        //delete [] atomBuffer;
    }
    // Add triangles to surface
    {
        int triangleBuffer[theSphere.nFlatTriangles()*3];// = new int[theSphere.nFlatTriangles()*3];
        int drawCount = 0;
		std::list<CXXSphereFlatTriangle, CXX::CXXAlloc<CXXSphereFlatTriangle> >::const_iterator trianglesEnd = 
		theSphere.getFlatTriangles().end();
		for (std::list<CXXSphereFlatTriangle, CXX::CXXAlloc<CXXSphereFlatTriangle> >::const_iterator triangle = 
			 theSphere.getFlatTriangles().begin();
			 triangle != trianglesEnd;
			 ++triangle){
			const CXXSphereFlatTriangle &theTriangle(*triangle);
            if (theTriangle.doDraw()){
                if (sense == CXXSphereElement::Contact || 
                    sense == CXXSphereElement::VDW ||
                    sense == CXXSphereElement::Accessible){
                    for (unsigned int j=0; j<3; j++){
                        int index = equivalence[theTriangle[2-j]];
                        triangleBuffer[3*drawCount+j] = index + oldVertexCount;
                    }
                }
                else {
                    for (unsigned int j=0; j<3; j++){
                        int index = equivalence[theTriangle[j]];
                        triangleBuffer[3*drawCount+j] = index + oldVertexCount;
                    }
                }
                drawCount++;
            }
        }
        extendTriangles(triangleBuffer, drawCount);
        //delete [] triangleBuffer;
    }
    return 0;
}
示例#4
0
/**
 * Returns whether this object has a valid shape
 * @returns True if the entire MeshObject may enclose
 * one or more volumes.
 */
bool MeshObject::hasValidShape() const {
  // May enclose volume if there are at
  // at least 4 triangles and 4 vertices (Tetrahedron)
  return (numberOfTriangles() >= 4 && numberOfVertices() >= 4);
}
示例#5
0
bool TissueState::exportToDbTables(const int ImageHeight, ofstream& framesFile, ofstream &verticesFile, ofstream &cellsFile, ofstream &ignoredCellsFile, ofstream &undirectedBondsFile, ofstream &directedBondsFile, unsigned long &lastVid, unsigned long &lastDbid, unsigned long &lastUbid) const {
  if(contains(Cell::VoidCellId)) {
    std::cout << "Found void cell id " << Cell::VoidCellId << " in frame " << _frameNumber << "!" << std::endl;
    return false;
  }
  
  // add data to frames table
  framesFile << _frameNumber << LogFile::DataSeparator << _time << '\n';
  if(framesFile.bad()) {
    std::cout << "Error writing frame data!" << std::endl;
    return false;
  }
  
  // add data to vertex table and generate map: vertex pointer -> vid
  std::map<Vertex*,unsigned long> vertexPointerToVid;
  for(int i=0; i<numberOfVertices(); ++i) {
    Vertex *v = vertex(i);
    ++lastVid;
    vertexPointerToVid[v] = lastVid;
    // write data:
    verticesFile << _frameNumber << LogFile::DataSeparator << lastVid << LogFile::DataSeparator << v->r.x() << LogFile::DataSeparator << ImageHeight-1-v->r.y() << '\n';
    if(verticesFile.bad()) {
      std::cout << "Error writing vertex data!" << std::endl;
      return false;
    }
  }
  
  // add data to cell table and generate map for bond sorting within cells
  std::map<DirectedBond*,DirectedBond*> leftBondSeenFromCellMap;
  // void cell
  cellsFile << _frameNumber << LogFile::DataSeparator << Cell::VoidCellId
          << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 
          << LogFile::DataSeparator << -1 << LogFile::DataSeparator << -1 << LogFile::DataSeparator << 0 
          << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 
          << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 
          << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 
          << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 << LogFile::DataSeparator << 0 
          << '\n';
  // other cells
  for(TissueState::CellConstIterator it=beginCellIterator(); it!=endCellIterator(); ++it) {
    Cell *c = cell(it);
    for(unsigned int j=0; j<c->bonds.size(); ++j) {
      leftBondSeenFromCellMap[c->bonds[j]] = c->bonds[(j+1)%c->bonds.size()];
    }
    // write data; revert signs of nematic xy components such that the values in the .dat files corresponds to a coordinate system with the y axis pointing upwards
    cellsFile << _frameNumber << LogFile::DataSeparator << c->id
            << LogFile::DataSeparator << (int)c->duringTransitionBefore << LogFile::DataSeparator << (int)c->duringTransitionAfter << LogFile::DataSeparator << c->daughter
            << LogFile::DataSeparator << c->r.x() << LogFile::DataSeparator << ImageHeight-1-c->r.y() << LogFile::DataSeparator << c->area
            << LogFile::DataSeparator << c->elongation.c1() << LogFile::DataSeparator << -c->elongation.c2()
            << LogFile::DataSeparator << c->polarityR.c1() << LogFile::DataSeparator << -c->polarityR.c2() << LogFile::DataSeparator << c->intIntensityR
            << LogFile::DataSeparator << c->polarityG.c1() << LogFile::DataSeparator << -c->polarityG.c2() << LogFile::DataSeparator << c->intIntensityG
            << LogFile::DataSeparator << c->polarityB.c1() << LogFile::DataSeparator << -c->polarityB.c2() << LogFile::DataSeparator << c->intIntensityB
            << '\n';
    if(cellsFile.bad()) {
      std::cout << "Error writing cell data!" << std::endl;
      return false;
    }
  }

  // ignored cells
  for(set<CellIndex>::const_iterator it=_ignoredCells.begin(); it!=_ignoredCells.end(); ++it) {
    // write data:
    ignoredCellsFile << _frameNumber << LogFile::DataSeparator << *it << '\n';
    if(ignoredCellsFile.bad()) {
      std::cout << "Error writing data for ignored cells!" << std::endl;
      return false;
    }
  }

   
  // add data to undirected bonds table and generate map: bond pointer -> dbid
  std::map<DirectedBond*,unsigned long> directedBondPointerToDbid;
  std::map<DirectedBond*,unsigned long> directedBondPointerToUbid;
  std::map<DirectedBond*,unsigned long> newConjBondDbids;
  std::map<DirectedBond*,DirectedBond*> newConjBondLeftOfConjBondAsSeenFromVoidCell;
  for(TissueState::BondConstIterator it=beginBondIterator(); it!=endBondIterator(); ++it) {
    DirectedBond *b = bond(it);
    ++lastDbid;
    directedBondPointerToDbid[b] = lastDbid;
    if(!b->conjBond) {
      ++lastDbid;
      newConjBondDbids[b] = lastDbid;
      
      // conj bond of bond left of conj bond seen from void cell
      Vertex *v = b->rightVertex;
      unsigned int i;
      for(i=0; i<v->bonds.size(); ++i) {
        if(v->bonds[i]==b) break;
      }
      if(i==v->bonds.size()) {
        std::cout << "TissueState::exportToDbTables: bond not found within rightVertex!" << std::endl;
        throw std::exception();
      }
      DirectedBond *oneBondCwAtVertex = v->bonds[ (i+v->bonds.size()-1)%v->bonds.size() ];
      
      Cell *c = oneBondCwAtVertex->cell;
      for(i=0; i<c->bonds.size(); ++i) {
        if(c->bonds[i]==oneBondCwAtVertex) break;
      }
      if(i==c->bonds.size()) {
        std::cout << "TissueState::exportToDbTables: bond not found within cell!" << std::endl;
        throw std::exception();
      }
      DirectedBond *oneBondCwAtCell = c->bonds[ (i+c->bonds.size()-1)%c->bonds.size() ];
      
      newConjBondLeftOfConjBondAsSeenFromVoidCell[b] = oneBondCwAtCell;
    }
    if((!b->conjBond) || (directedBondPointerToUbid.count(b->conjBond)==0)) {
      ++lastUbid;
      directedBondPointerToUbid[b] = lastUbid;
      undirectedBondsFile << _frameNumber << LogFile::DataSeparator << lastUbid << LogFile::DataSeparator << b->length << '\n';
      if(undirectedBondsFile.bad()) {
        std::cout << "Error writing undirectedBond data!" << std::endl;
        return false;
      }     
    } else {
      directedBondPointerToUbid[b] = directedBondPointerToUbid.at(b->conjBond);
    }
  }
  
  // add data to directed bonds table
  for(TissueState::BondConstIterator it=beginBondIterator(); it!=endBondIterator(); ++it) {
    DirectedBond *b = bond(it);
    if(b->conjBond) {
      directedBondsFile << _frameNumber << LogFile::DataSeparator << directedBondPointerToDbid.at(b) << LogFile::DataSeparator << directedBondPointerToDbid.at(b->conjBond) << LogFile::DataSeparator << directedBondPointerToUbid.at(b) << LogFile::DataSeparator << b->cell->id << LogFile::DataSeparator << vertexPointerToVid[b->rightVertex] << LogFile::DataSeparator << directedBondPointerToDbid.at(leftBondSeenFromCellMap.at(b)) << '\n';
      if(directedBondsFile.bad()) {
        std::cout << "Error writing directedBond data!" << std::endl;
        return false;
      }     
    } else {
      // add bond
      directedBondsFile << _frameNumber << LogFile::DataSeparator << directedBondPointerToDbid.at(b) << LogFile::DataSeparator << newConjBondDbids.at(b) << LogFile::DataSeparator << directedBondPointerToUbid.at(b) << LogFile::DataSeparator << b->cell->id << LogFile::DataSeparator << vertexPointerToVid[b->rightVertex] << LogFile::DataSeparator << directedBondPointerToDbid.at(leftBondSeenFromCellMap.at(b)) << '\n';
      if(directedBondsFile.bad()) {
        std::cout << "Error writing directedBond data!" << std::endl;
        return false;
      }
      // add new conj bond
      DirectedBond *conjBondOfLeftBondAsSeenFromVoidCell = newConjBondLeftOfConjBondAsSeenFromVoidCell.at(b);
      if(newConjBondDbids.count(conjBondOfLeftBondAsSeenFromVoidCell)==0) {
        std::cout << "TissueState::exportToDbTables: Problem with margin bonds!" << std::endl;
        throw std::exception();
      }
      directedBondsFile << _frameNumber << LogFile::DataSeparator << newConjBondDbids.at(b) << LogFile::DataSeparator << directedBondPointerToDbid.at(b) << LogFile::DataSeparator << directedBondPointerToUbid.at(b) << LogFile::DataSeparator << Cell::VoidCellId << LogFile::DataSeparator << vertexPointerToVid[b->leftVertex] << LogFile::DataSeparator << newConjBondDbids.at(conjBondOfLeftBondAsSeenFromVoidCell) << '\n';
      if(directedBondsFile.bad()) {
        std::cout << "Error writing directedBond data!" << std::endl;
        return false;
      }     
    }
  }
  
  return true;
}