/**************************************************************************** * 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, °ree, 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; }
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'; }
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 }