示例#1
0
文件: fr_dll.c 项目: jakobkroeker/fr
/****************************************************************************
 * real_roots of polynomial (in increasing degree)
 ****************************************************************************/
static Obj REAL_ROOTS (Obj self, Obj coeffs)
{
  Obj result;
  Int i, numroots;
  int degree = LEN_PLIST(coeffs)-1;
  Cdouble opr[degree+1], zeror[degree], zeroi[degree];

  if (degree < 1)
    return Fail;

  for (i = 0; i <= degree; i++) {
    opr[degree-i] = VAL_FLOAT(ELM_PLIST(coeffs,i+1));
    if (isnan(opr[degree-i]))
      return Fail;
  }

  rpoly (opr, &degree, zeror, zeroi);
  numroots = degree;

  if (numroots < 0)
    return Fail;

  result = ALLOC_PLIST(numroots);
  for (i = 1; i <= numroots; i++) {
    if (zeroi[i-1] == 0.0)
      set_elm_plist(result,i, NEW_FLOAT(zeror[i-1]));
    else {
      Obj t = ALLOC_PLIST(2);
      set_elm_plist(t,1, NEW_FLOAT(zeror[i-1]));
      set_elm_plist(t,2, NEW_FLOAT(zeroi[i-1]));
      set_elm_plist(result,i, t);
    }
  }
  return result;
}
示例#2
0
int
main()
{
  using Rat = __gnu_cxx::_Rational<int>;

  std::cout << Rat(1, 2) + Rat(1, 3) << '\n';
  std::cout << Rat(1, 2) - Rat(1, 3) << '\n';
  std::cout << Rat(1, 2) * Rat(1, 3) << '\n';
  std::cout << Rat(1, 2) / Rat(1, 3) << '\n';

  __gnu_cxx::_Polynomial<Rat> rpoly{{1,2}, {3, 4}, {5, 6}, {7, 8}};
  std::cout << "P = " << rpoly << '\n';
  for (int i = 0; i <= 10; ++i)
    std::cout << "P(" << i << ") = " << rpoly(i*1.0) << '\n';
}
示例#3
0
OCPNRegion ViewPort::GetVPRegionIntersect( const OCPNRegion &Region, size_t nPoints, float *llpoints,
        int chart_native_scale, wxPoint *ppoints )
{
    //  Calculate the intersection between a given OCPNRegion (Region) and a polygon specified by lat/lon points.

    //    If the viewpoint is highly overzoomed wrt to chart native scale, the polygon region may be huge.
    //    This can be very expensive, and lead to crashes on some platforms (gtk in particular)
    //    So, look for this case and handle appropriately with respect to the given Region

    if( chart_scale < chart_native_scale / 10 ) {

        //    Scan the points one-by-one, so that we can get min/max to make a bbox
        float *pfp = llpoints;
        float lon_max = -10000.;
        float lon_min = 10000.;
        float lat_max = -10000.;
        float lat_min = 10000.;

        for( unsigned int ip = 0; ip < nPoints; ip++ ) {
            lon_max = wxMax(lon_max, pfp[1]);
            lon_min = wxMin(lon_min, pfp[1]);
            lat_max = wxMax(lat_max, pfp[0]);
            lat_min = wxMin(lat_min, pfp[0]);

            pfp += 2;
        }

        LLBBox chart_box;
        chart_box.Set( lat_min, lon_min, lat_max, lon_max );

        //    Case:  vpBBox is completely outside the chart box, or vice versa
        //    Return an empty region
        if( chart_box.IntersectOut( vpBBox ) )
            return OCPNRegion();

        //    Case:  vpBBox is completely inside the chart box
        //      Note that this test is not perfect, and will fail for some charts.
        //      The chart coverage may be  essentially triangular, and the viewport box
        //      may be in the "cut off" segment of the chart_box, and not actually
        //      exhibit any true overlap.  Results will be reported incorrectly.
        //      How to fix: maybe scrub the chart points and see if it is likely that
        //      a region may be safely built and intersection tested.

        if( chart_box.IntersectIn( vpBBox ) )
            return Region;

        wxPoint p1 = GetPixFromLL( lat_max, lon_min );  // upper left
        wxPoint p2 = GetPixFromLL( lat_min, lon_max );   // lower right

        OCPNRegion r( p1, p2 );
        r.Intersect( Region );
        return r;
    }

    //    More "normal" case

    wxPoint *pp;

    //    Use the passed point buffer if available
    if( ppoints == NULL ) pp = new wxPoint[nPoints];
    else
        pp = ppoints;

    float *pfp = llpoints;


    wxPoint p = GetPixFromLL( pfp[0], pfp[1] );
    int poly_x_max, poly_y_max, poly_x_min, poly_y_min;

    bool valid = false;
    for( unsigned int ip = 0; ip < nPoints; ip++ ) {
        wxPoint p = GetPixFromLL( pfp[0], pfp[1] );
        pp[ip] = p;
        if(p.x == INVALID_COORD)
            continue;

        if(valid) {
            poly_x_max = wxMax(poly_x_max, p.x);
            poly_y_max = wxMax(poly_y_max, p.y);
            poly_x_min = wxMin(poly_x_min, p.x);
            poly_y_min = wxMin(poly_y_min, p.y);
        } else {
            poly_x_max = p.x;
            poly_y_max = p.y;
            poly_x_min = p.x;
            poly_y_min = p.y;
            valid = true;
        }
        pfp += 2;
    }

    if(!valid)
    {
        delete[] pp;
        return OCPNRegion(); //empty;
    }

    //  We want to avoid processing regions with very large rectangle counts,
    //  so make some tests for special cases

    float_2Dpt p0, p1, p2, p3;

    //  First, calculate whether any segment of the input polygon intersects the specified Region
    int nrect = 0;
    bool b_intersect = false;
    OCPNRegionIterator screen_region_it1( Region );
    while( screen_region_it1.HaveRects() ) {
        wxRect rect = screen_region_it1.GetRect();

        double lat, lon;

        //  The screen region corners
        GetLLFromPix( wxPoint(rect.x, rect.y), &lat, &lon );
        p0.y = lat;
        p0.x = lon;

        GetLLFromPix( wxPoint(rect.x + rect.width, rect.y), &lat, &lon );
        p1.y = lat;
        p1.x = lon;

        GetLLFromPix( wxPoint(rect.x + rect.width, rect.y + rect.height), &lat, &lon );
        p2.y = lat;
        p2.x = lon;

        GetLLFromPix( wxPoint(rect.x, rect.y + rect.height), &lat, &lon );
        p3.y = lat;
        p3.x = lon;


        for(size_t i=0 ; i < nPoints-1 ; i++) {
            //  Quick check on y dimension
            int y0 = pp[i].y;
            int y1 = pp[i+1].y;

            if(y0 == INVALID_COORD || y1 == INVALID_COORD)
                continue;

            if( ((y0 < rect.y) && (y1 < rect.y)) ||
                    ((y0 > rect.y+rect.height) && (y1 > rect.y+rect.height)) )
                continue;               // both ends of line outside of box, top or bottom

            //  Look harder
            float_2Dpt f0;
            f0.y = llpoints[i * 2];
            f0.x = llpoints[(i * 2) + 1];
            float_2Dpt f1;
            f1.y = llpoints[(i+1) * 2];
            f1.x = llpoints[((i+1) * 2) + 1];
            b_intersect |= Intersect_FL( p0, p1, f0, f1) != 0;
            if(b_intersect) break;
            b_intersect |= Intersect_FL( p1, p2, f0, f1) != 0;
            if(b_intersect) break;
            b_intersect |= Intersect_FL( p2, p3, f0, f1) != 0;
            if(b_intersect) break;
            b_intersect |= Intersect_FL( p3, p0, f0, f1) != 0;
            if(b_intersect) break;

            //  Must check the case where the input polygon has been pre-normalized, eg (0 < lon < 360), as cm93
            f0.x -= 360.;
            f1.x -= 360.;
            b_intersect |= Intersect_FL( p0, p1, f0, f1) != 0;
            if(b_intersect) break;
            b_intersect |= Intersect_FL( p1, p2, f0, f1) != 0;
            if(b_intersect) break;
            b_intersect |= Intersect_FL( p2, p3, f0, f1) != 0;
            if(b_intersect) break;
            b_intersect |= Intersect_FL( p3, p0, f0, f1) != 0;
            if(b_intersect) break;

        }

        // Check segment, last point back to first point
        if(!b_intersect) {

            float_2Dpt f0;
            f0.y = llpoints[(nPoints-1) * 2];
            f0.x = llpoints[((nPoints-1) * 2) + 1];
            float_2Dpt f1;
            f1.y = llpoints[0];
            f1.x = llpoints[1];
            b_intersect |= Intersect_FL( p0, p1, f0, f1) != 0;
            b_intersect |= Intersect_FL( p1, p2, f0, f1) != 0;
            b_intersect |= Intersect_FL( p2, p3, f0, f1) != 0;
            b_intersect |= Intersect_FL( p3, p0, f0, f1) != 0;

            f0.x -= 360.;
            f1.x -= 360.;
            b_intersect |= Intersect_FL( p0, p1, f0, f1) != 0;
            b_intersect |= Intersect_FL( p1, p2, f0, f1) != 0;
            b_intersect |= Intersect_FL( p2, p3, f0, f1) != 0;
            b_intersect |= Intersect_FL( p3, p0, f0, f1) != 0;

        }

        screen_region_it1.NextRect();
        nrect++;
    }

    //  If there is no itersection, we need to consider the case where
    //  the subject polygon is entirely within the Region
    bool b_contained = false;
    if(!b_intersect) {
        OCPNRegionIterator screen_region_it2( Region );
        while( screen_region_it2.HaveRects() ) {
            wxRect rect = screen_region_it2.GetRect();

            for(size_t i=0 ; i < nPoints-1 ; i++) {
                int x0 = pp[i].x;
                int y0 = pp[i].y;
                if(x0 == INVALID_COORD)
                    continue;

                if((x0 < rect.x) || (x0 > rect.x+rect.width))
                    continue;

                if((y0 < rect.y) || (y0 > rect.y+rect.height))
                    continue;

                b_contained = true;
                break;
            }
            screen_region_it2.NextRect();
        }
    }

#if 1
    // and here is the payoff
    if(!b_contained && !b_intersect) {
        //  Two cases to consider
        wxRect rpoly( poly_x_min, poly_y_min, poly_x_max - poly_x_min , poly_y_max - poly_y_min);
        wxRect rRegion = Region.GetBox();
        if(rpoly.Contains(rRegion)) {
            //  subject poygon may be large enough to fully encompass the target Region,
            //  but it might not, especially for irregular or concave charts.
            //  So we cannot directly shortcut here
            //  Better check....

#if 1
            if(nrect == 1) {                // most common case
                // If the subject polygon contains the center of the target rectangle, then
                // the intersection must be the target rectangle
                float rlat = (p0.y + p2.y)/2.;
                float rlon = (p0.x + p1.x)/2.;

                if(G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
                    if( NULL == ppoints ) delete[] pp;
                    return Region;
                }
                rlon += 360.;
                if(G_PtInPolygon_FL((float_2Dpt *)llpoints, nPoints, rlon, rlat)) {
                    if( NULL == ppoints ) delete[] pp;
                    return Region;
                }

                //  otherwise, there is no intersection
                else {
                    if( NULL == ppoints ) delete[] pp;
                    wxRegion r;
                    return r;
                }
            }

#endif

        }
        else {
            //  Subject polygon is entirely outside of target Region
            //  so the intersection must be empty.
            if( NULL == ppoints ) delete[] pp;
            wxRegion r;
            return r;
        }
    }
    else if(b_contained && !b_intersect) {
        //  subject polygon is entirely withing the target Region,
        //  so the intersection is the subject polygon
        OCPNRegion r = OCPNRegion( nPoints, pp );
        if( NULL == ppoints ) delete[] pp;
        return r;
    }

#endif


#ifdef __WXGTK__
    sigaction(SIGSEGV, NULL, &sa_all_old);             // save existing action for this signal

    struct sigaction temp;
    sigaction(SIGSEGV, NULL, &temp);// inspect existing action for this signal

    temp.sa_handler = catch_signals;// point to my handler
    sigemptyset(&temp.sa_mask);// make the blocking set
    // empty, so that all
    // other signals will be
    // unblocked during my handler
    temp.sa_flags = 0;
    sigaction(SIGSEGV, &temp, NULL);

    if(sigsetjmp(env, 1))//  Something in the below code block faulted....
    {
        sigaction(SIGSEGV, &sa_all_old, NULL);        // reset signal handler

        return Region;

    }

    else
    {

        OCPNRegion r = OCPNRegion(nPoints, pp);
        if(NULL == ppoints)
            delete[] pp;

        sigaction(SIGSEGV, &sa_all_old, NULL);        // reset signal handler
        r.Intersect(Region);
        return r;
    }

#else
    OCPNRegion r = OCPNRegion( nPoints, pp );

    if( NULL == ppoints ) delete[] pp;

    r.Intersect( Region );
    return r;

#endif
}