double TileSetLLByPixelArea::calcTriangleNDCAreaVisible(Plane const &clip_plane,
                                                        osg::Matrixd const &mvp,
                                                        std::vector<osg::Vec3d> const &tri,
                                                        std::vector<osg::Vec2d> const &tri_ndc) const
{
    bool ok;
    double area=0.0;

    // NDC bounding rectangle
    static const std::vector<osg::Vec2d> ndc_rect = {
        osg::Vec2d(-1.0,-1.0),    // bl
        osg::Vec2d( 1.0,-1.0),    // br
        osg::Vec2d( 1.0, 1.0),    // tr
        osg::Vec2d(-1.0, 1.0)     // tl
    };

    std::vector<osg::Vec3d> inside;
    std::vector<osg::Vec3d> outside;

    GeometryResult const result =
            CalcTrianglePlaneClip(tri,
                                  clip_plane,
                                  inside,
                                  outside);

    if(result == GeometryResult::CLIP_OUTSIDE) {
        // Completely outside the near plane
        if(CalcTriangleAARectIntersection(tri_ndc,ndc_rect)) {
            area += CalcTriangleArea(tri_ndc[0],tri_ndc[1],tri_ndc[2]);
        }
    }
    else if(result == GeometryResult::CLIP_XSEC) {
        // Triangle was clipped against the clip plane.
        // Use the outside tri or quad to calculate area
        std::vector<osg::Vec2d> list_ndc;
        for(auto const & vx : outside) {
            list_ndc.push_back(ConvWorldToNDC(mvp,vx,ok));
        }
        if(list_ndc.size() > 3) { // outside is a quad
            if(CalcQuadAARectIntersection(list_ndc,ndc_rect)) {
                area += CalcTriangleArea(list_ndc[0],list_ndc[1],list_ndc[2]);
                area += CalcTriangleArea(list_ndc[0],list_ndc[2],list_ndc[3]);
            }
        }
        else { // outside is a tri
            if(CalcTriangleAARectIntersection(list_ndc,ndc_rect)) {
                area += CalcTriangleArea(list_ndc[0],list_ndc[1],list_ndc[2]);
            }
        }
    }

    return area;
}
double TileSetLLByPixelArea::calcTriangleNDCAreaFull(Plane const &clip_plane,
                                                     osg::Matrixd const &mvp,
                                                     std::vector<osg::Vec3d> const &tri,
                                                     std::vector<osg::Vec2d> const &tri_ndc) const
{
    bool ok;
    double area=0.0;

    std::vector<osg::Vec3d> inside;
    std::vector<osg::Vec3d> outside;

    GeometryResult const result =
            CalcTrianglePlaneClip(tri,
                                  clip_plane,
                                  inside,
                                  outside);

    if(result == GeometryResult::CLIP_OUTSIDE) {
        // Completely outside the near plane
        area += CalcTriangleArea(tri_ndc[0],tri_ndc[1],tri_ndc[2]);
    }
    else if(result == GeometryResult::CLIP_XSEC) {
        // Triangle was clipped against the clip plane.
        // Use the outside tri or quad to calculate area
        std::vector<osg::Vec2d> list_ndc;
        for(auto const & vx : outside) {
            list_ndc.push_back(ConvWorldToNDC(mvp,vx,ok));
        }

        if(list_ndc.size() > 3) { // outside is a quad
            area += CalcTriangleArea(list_ndc[0],list_ndc[1],list_ndc[2]);
            area += CalcTriangleArea(list_ndc[0],list_ndc[2],list_ndc[3]);
        }
        else { // outside is a tri
            area += CalcTriangleArea(list_ndc[0],list_ndc[1],list_ndc[2]);
        }
    }

    return area;
}
Beispiel #3
0
double CalcFaceArea (FacePtr pFace)
{	SidePtr		pS;		// to loop over a Face's Sides
	double		Area;	// Face area
	Loc3DTD		FC;		// Face centroid
	
	CalcFaceCentroidFromNodes ( pFace );
	FC   = pFace->Centroid;
	Area = 0.0;
	
	pS = pFace->p1stSide;
	while (pS != NULL)
	{	
		Area = Area + CalcTriangleArea (FC, pS->pNode1->Loc3D, pS->pNode2->Loc3D);
		pS = pS->pFsNextS;
	}
	return (Area);
}
Beispiel #4
0
/**
 * 多角形の面積を計算.
 */
double MathUtil::CalcPolygonArea (sxsdk::shade_interface& shade, std::vector<sxsdk::vec3>& polygon)
{
	if (polygon.size() < 3) return 0.0;

	// 三角形分割を行う.
	::m_triangleIndex.clear();
	::CDivideTrianglesOutput divC;
	shade.divide_polygon(divC, polygon.size(), &(polygon[0]), true);
	const int triCou = ::m_triangleIndex.size() / 3;

	double area = 0.0;
	int iPos = 0;
	for (int i = 0; i < triCou; i++, iPos += 3) {
		const int i0 = ::m_triangleIndex[iPos + 0];
		const int i1 = ::m_triangleIndex[iPos + 1];
		const int i2 = ::m_triangleIndex[iPos + 2];

		area += CalcTriangleArea(polygon[i0], polygon[i1], polygon[i2]);
	}
	return area;
}
void TileSetLLByPixelArea::calcTileNDCArea(Eval const &eval,
                                           double &ndc_area,
                                           double &surf_area_m2) const
{
    // Find a quads that are completely visible
    // (not clipped) and calculate both its pixel
    // and surface areas

    ndc_area = 0.0;
    surf_area_m2 = 0.0;

    // For each quad
    for(size_t i=0; i < eval.list_ix.size(); i+=6) {
        // Ignore quads that face away from the camera
        if((eval.list_quad_nx[i/6]*m_view_dirn) >= -0.01) { // TODO experiment adjusting threshold
            continue;
        }

        bool bad_tri=false;

        // Try converting first tri to NDC
        std::vector<osg::Vec3d> const tri0 = {
            eval.list_vx[eval.list_ix[i+0]],
            eval.list_vx[eval.list_ix[i+1]],
            eval.list_vx[eval.list_ix[i+2]]
        };
        std::vector<osg::Vec2d> tri0_ndc(3);
        for(size_t j=0; j < 3; j++) {
            if(!ConvWorldToNDC(m_mvp,tri0[j],tri0_ndc[j])) {
                bad_tri=true;
                break;
            }
        }
        if(bad_tri) {
            continue;
        }

        // Try converting second tri to NDC
        std::vector<osg::Vec3d> const tri1 = {
            eval.list_vx[eval.list_ix[i+3]],
            eval.list_vx[eval.list_ix[i+4]],
            eval.list_vx[eval.list_ix[i+5]]
        };
        std::vector<osg::Vec2d> tri1_ndc(3);
        for(size_t j=0; j < 3; j++) {
            if(!ConvWorldToNDC(m_mvp,tri1[j],tri1_ndc[j])) {
                bad_tri=true;
                break;
            }
        }
        if(bad_tri) {
            continue;
        }

        // Add NDC area
        double tri0_area = CalcTriangleArea(tri0_ndc[0],tri0_ndc[1],tri0_ndc[2]);
        double tri1_area = CalcTriangleArea(tri1_ndc[0],tri1_ndc[1],tri1_ndc[2]);

        ndc_area += tri0_area;
        ndc_area += tri1_area;

        // Add surface area
        std::vector<LLA> const tri0_lla = {
            eval.list_lla[eval.list_ix[i+0]],
            eval.list_lla[eval.list_ix[i+1]],
            eval.list_lla[eval.list_ix[i+2]]
        };

        // lon range for surface area
        auto list_lon_ranges = CalcLonRange(tri0_lla);
        if(list_lon_ranges.size() > 1) {
            // We might get two ranges due to numerical
            // precision issues near the antemeridian;
            // discard the smaller range
            double range0 =
                    list_lon_ranges[0].second-
                    list_lon_ranges[0].first;

            double range1 =
                    list_lon_ranges[1].second-
                    list_lon_ranges[1].first;

            if(range0 > range1) {
                list_lon_ranges.pop_back();
            }
            else {
                list_lon_ranges.erase(list_lon_ranges.begin());
            }
        }
        // lat range for surface area
        std::pair<double,double> lat_range(90.0,-90.0);
        for(auto const &lla : tri0_lla) {
            lat_range.first  = std::min(lat_range.first,lla.lat);
            lat_range.second = std::max(lat_range.second,lla.lat);
        }

        GeoBounds const bounds(list_lon_ranges[0].first,
                               list_lon_ranges[0].second,
                               lat_range.first,
                               lat_range.second);

//        std::cout << "####: ndirn: " << (eval.list_quad_nx[i/6]*m_view_dirn) << std::endl;
//        std::cout << "####: tri0_area: " << tri0_area << ", tri1_area: " << tri1_area << std::endl;
//        std::cout << "####: bounds.lon [" << bounds.minLon << "," << bounds.maxLon << "]" << std::endl;
//        std::cout << "####: bounds.lat [" << bounds.minLat << "," << bounds.maxLat << "]" << std::endl;
//        std::cout << "####: bounds.area: " << CalcGeoBoundsArea(bounds) << std::endl;

        surf_area_m2 += CalcGeoBoundsArea(bounds);
    }
}