Exemple #1
0
void QTessellatorPrivate::addIntersections()
{
    if (scanline.size) {
        QDEBUG() << "INTERSECTIONS";
        // check marked edges for intersections
#ifdef DEBUG
        for (int i = 0; i < scanline.size; ++i) {
            Edge *e = scanline.edges[i];
            QDEBUG() << "    " << i << e->edge << "isect=(" << e->intersect_left << e->intersect_right
                     << ')';
        }
#endif

        for (int i = 0; i < scanline.size - 1; ++i) {
            Edge *e1 = scanline.edges[i];
            Edge *e2 = scanline.edges[i + 1];
            // check for intersection
            if (e1->intersect_right || e2->intersect_left)
                addIntersection(e1, e2);
        }
    }
#if 0
    if (intersections.constBegin().key().y == y) {
        QDEBUG() << "----------------> intersection on same line";
        scanline.clearMarks();
        scanline.processIntersections(y, &intersections);
        goto redo;
    }
#endif
}
bool ChartElemNavaids::addNewIntersection(const QString& intersection_id, QString& err_msg)
{
    const Waypoint* existing_intersection = getNavaid(intersection_id, Waypoint::INTERSECTION);
    if (existing_intersection)
    {
        err_msg = QString("Navaids:INTERSECTION: Intersection with ID (%1) already exists").
                  arg(intersection_id);
        return false;
    }

    Intersection *intersection = (Intersection*)m_chart_model->getNavdata()->getElementsWithSignal(
        intersection_id, "", Waypoint::INTERSECTION);
    
    if (!intersection)
    {
        err_msg = QString("Navaids:INTERSECTION: unknown intersection with ID (%1)").
                  arg(intersection_id);
        delete intersection;
        return false;
    }

    QDomDocument dom_doc = m_dom_element.ownerDocument();
    QDomElement new_element = dom_doc.createElement(CHART_NODE_NAME_NAVAIDS_INTERSECTION);
    m_dom_element.appendChild(new_element);

    bool ret = addIntersection(*intersection, new_element, dom_doc, err_msg);
    setProjectionCenterWhenAppropriate(intersection);
    delete intersection;
    return ret;
}
Exemple #3
0
/**
* Adds EdgeIntersections for one or both
* intersections found for a segment of an edge to the edge intersection list.
*/
void
SegmentString::addIntersections(LineIntersector *li, int segmentIndex, int geomIndex)
{
	for (int i=0; i<li->getIntersectionNum(); i++) {
		addIntersection(li,segmentIndex, geomIndex, i);
	}
}
/*public*/
void
NodedSegmentString::addIntersections(LineIntersector *li, unsigned int
		segmentIndex, int geomIndex)
{
	for (int i=0, n=li->getIntersectionNum(); i<n; ++i) {
		addIntersection(li, segmentIndex, geomIndex, i);
	}
}
Exemple #5
0
/**
 * Add an SegmentNode for intersection intIndex.
 * An intersection that falls exactly on a vertex
 * of the SegmentString is normalized
 * to use the higher of the two possible segmentIndexes
 */
void
SegmentString::addIntersection(LineIntersector *li, int segmentIndex, int geomIndex, int intIndex)
{
	const Coordinate &intPt=li->getIntersection(intIndex);
	double dist=li->getEdgeDistance(geomIndex, intIndex);
	addIntersection((Coordinate&)intPt, segmentIndex, dist);
	//delete intPt;
}
/*public*/
void
NodedSegmentString::addIntersection(LineIntersector *li,
		unsigned int segmentIndex,
		int geomIndex, int intIndex)
{
    ::geos::ignore_unused_variable_warning(geomIndex);

	const Coordinate &intPt=li->getIntersection(intIndex);
	addIntersection(intPt, segmentIndex);
}
        // handle points
        void operator()(const Vec3_type v1, bool /*treatVertexDataAsTemporary*/)
        {
            ++_index;
            if ((_dimensionMask & PolytopeIntersector::DimZero) == 0) return;

            if (_limitOneIntersection && !intersections.empty()) return;

            for (PlaneList::const_iterator it=_planes.begin(); it!=_planes.end(); ++it)
            {
                const osg::Plane& plane=*it;
                const value_type d1=plane.distance(v1);
                if (d1<0.0f) return;   // point outside
            }
            _candidates.clear();
            _candidates.push_back( CandList_t::value_type(_plane_mask, v1));
            addIntersection(_index, _candidates);
        }
bool ChartElemNavaids::addNewLatLonPoint(const QString& id, double lat, double lon, QString& err_msg)
{
    MYASSERT(!id.isEmpty());

    const Waypoint* existing_intersection = getNavaid(id, Waypoint::INTERSECTION);
    if (existing_intersection)
    {
        err_msg = 
            QString("Navaids:LATLONPOINT: Intersection with ID (%1) already exists").arg(id);
        return false;
    }

    Intersection *intersection = new Intersection(id, lat, lon, QString::null);
    MYASSERT(intersection != 0);

    QDomDocument dom_doc = m_dom_element.ownerDocument();
    QDomElement new_element = dom_doc.createElement(CHART_NODE_NAME_NAVAIDS_INTERSECTION);
    m_dom_element.appendChild(new_element);

    bool ret = addIntersection(*intersection, new_element, dom_doc, err_msg);
    setProjectionCenterWhenAppropriate(intersection);
    delete intersection;
    return ret;
}
Exemple #9
0
/**
 * Add an EdgeIntersection for intersection intIndex.
 * An intersection that falls exactly on a vertex of the edge is normalized
 * to use the higher of the two possible segmentIndexes
 */
void
SegmentString::addIntersection(Coordinate& intPt, int segmentIndex)
{
	double dist=LineIntersector::computeEdgeDistance(intPt,pts->getAt(segmentIndex),pts->getAt(segmentIndex + 1));
	addIntersection(intPt, segmentIndex, dist);
}
        // handle triangles
        void operator()(const Vec3_type v1, const Vec3_type v2, const Vec3_type v3, bool /*treatVertexDataAsTemporary*/)
        {
            ++_index;
            if ((_dimensionMask & PolytopeIntersector::DimTwo) == 0) return;

            if (_limitOneIntersection && !intersections.empty()) return;

            PlaneMask selector_mask = 0x1;
            PlaneMask inside_mask = 0x0;
            _candidates.clear();

            for(PlaneList::const_iterator it=_planes.begin();
                it!=_planes.end();
                ++it, selector_mask <<= 1)
            {
                const osg::Plane& plane=*it;
                const value_type d1=plane.distance(v1);
                const value_type d2=plane.distance(v2);
                const value_type d3=plane.distance(v3);
                const bool d1IsNegative = (d1<0.0f);
                const bool d2IsNegative = (d2<0.0f);
                const bool d3IsNegative = (d3<0.0f);
                if (d1IsNegative && d2IsNegative && d3IsNegative) return;      // triangle outside
                if (!d1IsNegative && !d2IsNegative && !d3IsNegative)
                {
                    inside_mask |= selector_mask;
                    continue;   // completly inside
                }

                // edge v1-v2 intersects
                if (d1==0.0f)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, v1) );
                }
                else if (d2==0.0f)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, v2) );
                }
                else if (d1IsNegative && !d2IsNegative)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, (v1-(v2-v1)*(d1/(-d1+d2))) ) );
                }
                else if (!d1IsNegative && d2IsNegative)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, (v1+(v2-v1)*(d1/(d1-d2))) ) );
                }

                // edge v1-v3 intersects
                if (d3==0.0f)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, v3) );
                }
                else if (d1IsNegative && !d3IsNegative)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, (v1-(v3-v1)*(d1/(-d1+d3))) ) );
                }
                else if (!d1IsNegative && d3IsNegative)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, (v1+(v3-v1)*(d1/(d1-d3))) ) );
                }

                // edge v2-v3 intersects
                if (d2IsNegative && !d3IsNegative)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, (v2-(v3-v2)*(d2/(-d2+d3))) ) );
                } else if (!d2IsNegative && d3IsNegative)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, (v2+(v3-v2)*(d2/(d2-d3))) ) );
                }
            }

            if (_plane_mask==inside_mask)
            { // triangle lies inside of all planes
                _candidates.push_back( CandList_t::value_type(_plane_mask, v1) );
                _candidates.push_back( CandList_t::value_type(_plane_mask, v2) );
                _candidates.push_back( CandList_t::value_type(_plane_mask, v3) );
                addIntersection(_index, _candidates);
                return;
            }

            if (_candidates.empty() && _planes.size()<3) return;

            unsigned int numCands=checkCandidatePoints(inside_mask);

            if (numCands>0)
            {
                addIntersection(_index, _candidates);
                return;
            }

            // handle case where the polytope goes through the triangle
            // without containing any point of it

            LinesList& lines=getPolytopeLines();
            _candidates.clear();

            // check all polytope lines against the triangle
            // use algorithm from "Real-time rendering" (second edition) pp.580
            const Vec3_type e1=v2-v1;
            const Vec3_type e2=v3-v1;

            for (LinesList::const_iterator it=lines.begin(); it!=lines.end(); ++it)
            {
                const PlanesLine& line=*it;

                Vec3_type p=line.dir^e2;
                const value_type a=e1*p;
                if (osg::absolute(a)<eps()) continue;

                const value_type f=1.0f/a;
                const Vec3_type s=(line.pos-v1);
                const value_type u=f*(s*p);
                if (u<0.0f || u>1.0f) continue;

                const Vec3_type q=s^e1;
                const value_type v=f*(line.dir*q);
                if (v<0.0f || u+v>1.0f) continue;

                const value_type t=f*(e2*q);

                _candidates.push_back(CandList_t::value_type(line.mask, line.pos+line.dir*t));
            }

            numCands=checkCandidatePoints(inside_mask);

            if (numCands>0)
            {
                addIntersection(_index, _candidates);
                return;
            }

        }
        // handle lines
        void operator()(const Vec3_type v1, const Vec3_type v2, bool /*treatVertexDataAsTemporary*/)
        {
            ++_index;
            if ((_dimensionMask & PolytopeIntersector::DimOne) == 0) return;

            if (_limitOneIntersection && !intersections.empty()) return;

            PlaneMask selector_mask = 0x1;
            PlaneMask inside_mask = 0x0;
            _candidates.clear();

            bool v1Inside = true;
            bool v2Inside = true;
            for (PlaneList::const_iterator it=_planes.begin(); it!=_planes.end(); ++it, selector_mask<<=1)
            {
                const osg::Plane& plane=*it;
                const value_type d1=plane.distance(v1);
                const value_type d2=plane.distance(v2);
                const bool d1IsNegative = (d1<0.0f);
                const bool d2IsNegative = (d2<0.0f);
                if (d1IsNegative && d2IsNegative) return;      // line outside

                if (!d1IsNegative && !d2IsNegative)
                {
                    inside_mask |= selector_mask;
                    continue;   // completly inside
                }
                if (d1IsNegative) v1Inside = false;
                if (d2IsNegative) v2Inside = false;
                if (d1==0.0f)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, v1) );
                }
                else if (d2==0.0f)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, v2) );
                }
                else if (d1IsNegative && !d2IsNegative)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, (v1-(v2-v1)*(d1/(-d1+d2))) ) );
                } else if (!d1IsNegative && d2IsNegative)
                {
                    _candidates.push_back( CandList_t::value_type(selector_mask, (v1+(v2-v1)*(d1/(d1-d2))) ) );
                }

                }
                if (inside_mask==_plane_mask)
                {
                    _candidates.push_back( CandList_t::value_type(_plane_mask, v1) );
                    _candidates.push_back( CandList_t::value_type(_plane_mask, v2) );
                    addIntersection(_index, _candidates);
                    return;
                }

            unsigned int numCands=checkCandidatePoints(inside_mask);
            if (numCands>0)
            {
                if (v1Inside) _candidates.push_back( CandList_t::value_type(_plane_mask, v1) );
                if (v2Inside) _candidates.push_back( CandList_t::value_type(_plane_mask, v2) );
                addIntersection(_index, _candidates);
            }

        }
bool ChartElemNavaids::loadFromDomElement(QDomElement& dom_element, 
                                          QDomDocument& dom_doc,
                                          QString& err_msg)
{
    MYASSERT(!dom_element.isNull());
    TreeBaseXML::loadFromDomElement(dom_element, dom_doc, err_msg);

    if (m_dom_element.tagName() != CHART_NODE_NAME_NAVAIDS)
    {
        err_msg = QString("Wrong node name (%s), expected (%s)").
                  arg(m_dom_element.tagName()).arg(CHART_NODE_NAME_NAVAIDS);
        return false;
    }

    // loop through all navaids

    QDomNode node = m_dom_element.firstChild();
    for(; !node.isNull(); node = node.nextSibling())
    {
        QDomElement element = node.toElement();
        if (element.isNull()) continue;

        // extract info from node

        QString id = element.attribute(CHART_ATTR_ID);
        QString ctry = element.attribute(CHART_ATTR_CTRY);
        QString name = element.attribute(CHART_ATTR_NAME);
        double lat = element.attribute(CHART_ATTR_LAT).toDouble();
        double lon = element.attribute(CHART_ATTR_LON).toDouble();
        int freq = element.attribute(CHART_ATTR_FREQ).toUInt();
        bool has_dme = element.attribute(CHART_ATTR_DME).toInt();
        int elevation = element.attribute(CHART_ATTR_ELEV).toInt();

        // check info

        if (id.isEmpty())
        {
            err_msg = QString("Navaids: Missing ID at tag named (%1)").arg(element.tagName());
            return false;
        }

        // process element

        if (element.tagName() == CHART_NODE_NAME_NAVAIDS_VOR)
        {
            Vor* vor = 0;

            if (!name.isEmpty() && lat != 0.0 && lon != 0.0 && freq != 0)
                vor = new Vor(id, name, lat, lon, freq, has_dme, 0, 0, ctry);
            else
                vor = (Vor*)m_chart_model->getNavdata()->getElementsWithSignal(
                    id, ctry, Waypoint::VOR);

            if (!vor)
            {
                err_msg = QString("Navaids:VOR: unknown VOR with ID (%1)").arg(id);
                return false;
            }

            if (!addVor(*vor, element, dom_doc, err_msg))
            {
                node = node.previousSibling();
                m_dom_element.removeChild(element);
            }
            
            delete vor;
        }
        else if (element.tagName() == CHART_NODE_NAME_NAVAIDS_NDB)
        {
            Ndb* ndb = 0;

            if (!name.isEmpty() && lat != 0.0 && lon != 0.0 && freq != 0)
                ndb = new Ndb(id, name, lat, lon, freq, 0, 0, ctry);
            else
                ndb = (Ndb*)m_chart_model->getNavdata()->getElementsWithSignal(
                    id, ctry, Waypoint::NDB);

            if (!ndb)
            {
                err_msg = QString("Navaids:NDB: unknown NDB with ID (%1)").arg(id);
                return false;
            }

            if (!addNdb(*ndb, element, dom_doc, err_msg))
            {
                node = node.previousSibling();
                m_dom_element.removeChild(element);
            }
            
            delete ndb;
        }
        else if (element.tagName() == CHART_NODE_NAME_NAVAIDS_AIRPORT)
        {
            Airport* airport = 0;

            if (!name.isEmpty() && lat != 0.0 && lon != 0.0 && 
                element.hasAttribute(CHART_ATTR_ELEV))
                airport = new Airport(id, name, lat, lon, elevation);
            else
                airport = (Airport*)m_chart_model->getNavdata()->getElementsWithSignal(
                    id, ctry, Waypoint::AIRPORT);

            if (!airport)
            {
                err_msg = QString("Navaids:AIRPORT: unknown AIRPORT with ID (%1)").arg(id);
                return false;
            }

            if (!addAirport(*airport, element, dom_doc, err_msg))
            {
                node = node.previousSibling();
                m_dom_element.removeChild(element);
            }

            delete airport;
        }
        else if (element.tagName() == CHART_NODE_NAME_NAVAIDS_INTERSECTION)
        {
            Intersection* intersection = 0;
            
            if (lat != 0.0 && lon != 0.0)
                intersection = new Intersection(id, lat, lon, ctry);
            else
                intersection = (Intersection*)m_chart_model->getNavdata()->getElementsWithSignal(
                    id, ctry, Waypoint::INTERSECTION);

            if (!intersection)
            {
                err_msg = 
                    QString("Navaids:INTERSECTION: unknown INTERSECTION with ID (%1)").arg(id);
                return false;
            }

            if (!addIntersection(*intersection, element, dom_doc, err_msg))
            {
                node = node.previousSibling();
                m_dom_element.removeChild(element);
            }

            delete intersection;
        }
    }
    
    return true;
}