PlugIn_ViewPort CreatePlugInViewport( const ViewPort &vp) { // Create a PlugIn Viewport ViewPort tvp = vp; PlugIn_ViewPort pivp; pivp.clat = tvp.clat; // center point pivp.clon = tvp.clon; pivp.view_scale_ppm = tvp.view_scale_ppm; pivp.skew = tvp.skew; pivp.rotation = tvp.rotation; pivp.chart_scale = tvp.chart_scale; pivp.pix_width = tvp.pix_width; pivp.pix_height = tvp.pix_height; pivp.rv_rect = tvp.rv_rect; pivp.b_quilt = tvp.b_quilt; pivp.m_projection_type = tvp.m_projection_type; pivp.lat_min = tvp.GetBBox().GetMinY(); pivp.lat_max = tvp.GetBBox().GetMaxY(); pivp.lon_min = tvp.GetBBox().GetMinX(); pivp.lon_max = tvp.GetBBox().GetMaxX(); pivp.bValid = tvp.IsValid(); // This VP is valid return pivp; }
void AppDelegate::initializeViewPort(CCSize viewSize, float scaleFactor) { // Divide by the scale factor so that the view port remains the same for retina devices (converts to points) viewSize.width /= scaleFactor; viewSize.height /= scaleFactor; ViewPort* viewPort = ViewPort::getInstance(); viewPort->initialize(viewSize); }
void Frustum::init(Window * p, Camera * c) { ViewPort vp = p->getViewPort(ViewPortMain); vp.getFrustum(nearp,farp,angle); this->camera = c; float tang = float(tan(M_PI * angle / 360.f)); float ratio = float(p->width) / p->height; nh = nearp * tang; nw = nh * ratio; fh = farp * tang; fw = fh * ratio; }
void ParallaxBackground::update(const ViewPort& viewPort) { for (auto& l : layers_) { auto& vpp = viewPort.getPosition(); l.sprite->setPosition(Vector2Glf(vpp(0) + (l.offset(0)-vpp(0))*l.parallaxRatio, vpp(1) + (l.offset(1)-vpp(1))*l.parallaxRatio)); } }
void Route::DrawGL( ViewPort &vp ) { #ifdef ocpnUSE_GL if( pRoutePointList->empty() || !m_bVisible ) return; if(!vp.GetBBox().IntersectOut(GetBBox())) DrawGLRouteLines(vp); /* Route points */ for(wxRoutePointListNode *node = pRoutePointList->GetFirst(); node; node = node->GetNext()) { RoutePoint *prp = node->GetData(); if ( !m_bVisible && prp->m_bKeepXRoute ) prp->DrawGL( vp ); else if (m_bVisible) prp->DrawGL( vp ); } #endif }
//! update viewports sizes void ShootEditor::UpdateViewPortsSizes() { if(EditorSettings::Instance()->WindowSize == EditorSettings::WS_Stretch) { ViewPort* pViewPort = GetViewPort(); pViewPort->SetPosition(wxPoint(0, 0)); pViewPort->SetSize(GetTabContainer()->GetViewPortContainer()->GetSize()); } else { Size size = EditorSettings::WindowSizes[EditorSettings::Instance()->WindowSize]; ViewPort* pViewPort = GetViewPort(); wxSize viewPortSize = pViewPort->GetSize(); wxPoint center = wxPoint((viewPortSize.x - size.Width)/2, (viewPortSize.y - size.Height)/2); pViewPort->SetPosition(center); pViewPort->SetSize(wxSize(size.Width, size.Height)); } }
void RoutePoint::DrawGL( ViewPort &vp, bool use_cached_screen_coords ) { if( !m_bIsVisible ) return; // Optimization, especially apparent on tracks in normal cases if( m_IconName == _T("empty") && !m_bShowName && !m_bPtIsSelected ) return; if(m_wpBBox.GetValid() && vp.view_scale_ppm == m_wpBBox_view_scale_ppm && vp.rotation == m_wpBBox_rotation) { /* see if this waypoint can intersect with bounding box */ LLBBox vpBBox = vp.GetBBox(); if( vpBBox.IntersectOut( m_wpBBox ) ){ // Are Range Rings enabled? if(m_bShowWaypointRangeRings && (m_iWaypointRangeRingsNumber > 0)){ double factor = 1.00; if( m_iWaypointRangeRingsStepUnits == 1 ) // convert kilometers to NMi factor = 1 / 1.852; double radius = factor * m_iWaypointRangeRingsNumber * m_fWaypointRangeRingsStep / 60.; LLBBox radar_box = m_wpBBox; radar_box.EnLarge(radius * 2 ); if( vpBBox.IntersectOut( radar_box ) ){ return; } } else return; } } wxPoint r; wxRect hilitebox; unsigned char transparency = 150; double platform_pen_width = wxRound(wxMax(1.0, g_Platform->GetDisplayDPmm() / 2)); // 0.5 mm nominal, but not less than 1 pixel if(use_cached_screen_coords && m_pos_on_screen) r.x = m_screen_pos.m_x, r.y = m_screen_pos.m_y; else cc1->GetCanvasPointPix( m_lat, m_lon, &r ); if(r.x == INVALID_COORD) return; // Substitute icon? wxBitmap *pbm; if( ( m_bIsActive ) && ( m_IconName != _T("mob") ) ) pbm = pWayPointMan->GetIconBitmap( _T ( "activepoint" ) ); else pbm = m_pbmIcon; // If icon is corrupt, there is really nothing else to do... if(!pbm->IsOk()) return; int sx2 = pbm->GetWidth() / 2; int sy2 = pbm->GetHeight() / 2; // Calculate the mark drawing extents wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 ); // the bitmap extents wxRect r3 = r1; if( m_bShowName ) { if( !m_pMarkFont ) { m_pMarkFont = FontMgr::Get().GetFont( _( "Marks" ) ); m_FontColor = FontMgr::Get().GetFontColor( _( "Marks" ) ); CalculateNameExtents(); } if( m_pMarkFont ) { wxRect r2( r.x + m_NameLocationOffsetX, r.y + m_NameLocationOffsetY, m_NameExtents.x, m_NameExtents.y ); r3.Union( r2 ); } } hilitebox = r3; hilitebox.x -= r.x; hilitebox.y -= r.y; hilitebox.x *= g_ChartScaleFactorExp; hilitebox.y *= g_ChartScaleFactorExp; hilitebox.width *= g_ChartScaleFactorExp; hilitebox.height *= g_ChartScaleFactorExp; float radius; if( g_btouch ){ hilitebox.Inflate( 20 ); radius = 20.0f; } else{ hilitebox.Inflate( 4 ); radius = 4.0f; } /* update bounding box */ if(!m_wpBBox.GetValid() || vp.view_scale_ppm != m_wpBBox_view_scale_ppm || vp.rotation != m_wpBBox_rotation) { double lat1, lon1, lat2, lon2; cc1->GetCanvasPixPoint(r.x+hilitebox.x, r.y+hilitebox.y+hilitebox.height, lat1, lon1); cc1->GetCanvasPixPoint(r.x+hilitebox.x+hilitebox.width, r.y+hilitebox.y, lat2, lon2); if(lon1 > lon2) m_wpBBox.Set(lat1, lon1, lat2, lon2+360); else m_wpBBox.Set(lat1, lon1, lat2, lon2); m_wpBBox_view_scale_ppm = vp.view_scale_ppm; m_wpBBox_rotation = vp.rotation; } // if(region.Contains(r3) == wxOutRegion) // return; ocpnDC dc; // Highlite any selected point if( m_bPtIsSelected ) { wxColour hi_colour; if( m_bBlink ){ wxPen *pen = g_pRouteMan->GetActiveRoutePointPen(); hi_colour = pen->GetColour(); } else{ hi_colour = GetGlobalColor( _T ( "YELO1" ) ); } AlphaBlending( dc, r.x + hilitebox.x, r.y + hilitebox.y, hilitebox.width, hilitebox.height, radius, hi_colour, transparency ); } bool bDrawHL = false; if( m_bBlink && ( gFrame->nBlinkerTick & 1 ) ) bDrawHL = true; if( ( !bDrawHL ) && ( NULL != m_pbmIcon ) ) { int glw, glh; unsigned int IconTexture = pWayPointMan->GetIconTexture( pbm, glw, glh ); glBindTexture(GL_TEXTURE_2D, IconTexture); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glColor3f(1, 1, 1); int x = r1.x, y = r1.y, w = r1.width, h = r1.height; float scale = 1.0; // if(g_bresponsive){ scale = g_ChartScaleFactorExp; // } float ws = r1.width * scale; float hs = r1.height * scale; float xs = r.x - ws/2.; float ys = r.y - hs/2.; float u = (float)w/glw, v = (float)h/glh; glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(xs, ys); glTexCoord2f(u, 0); glVertex2f(xs+ws, ys); glTexCoord2f(u, v); glVertex2f(xs+ws, ys+hs); glTexCoord2f(0, v); glVertex2f(xs, ys+hs); glEnd(); // glBegin(GL_QUADS); // glTexCoord2f(0, 0); glVertex2f(x, y); // glTexCoord2f(u, 0); glVertex2f(x+w, y); // glTexCoord2f(u, v); glVertex2f(x+w, y+h); // glTexCoord2f(0, v); glVertex2f(x, y+h); // glEnd(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } if( m_bShowName && m_pMarkFont ) { int w = m_NameExtents.x, h = m_NameExtents.y; if(!m_iTextTexture && w && h) { wxBitmap tbm(w, h); /* render text on dc */ wxMemoryDC dc; dc.SelectObject( tbm ); dc.SetBackground( wxBrush( *wxBLACK ) ); dc.Clear(); dc.SetFont( *m_pMarkFont ); dc.SetTextForeground( *wxWHITE ); dc.DrawText( m_MarkName, 0, 0); dc.SelectObject( wxNullBitmap ); /* make alpha texture for text */ wxImage image = tbm.ConvertToImage(); unsigned char *d = image.GetData(); unsigned char *e = new unsigned char[w * h]; if(d && e){ for( int p = 0; p < w*h; p++) e[p] = d[3*p + 0]; } /* create texture for rendered text */ glGenTextures(1, &m_iTextTexture); glBindTexture(GL_TEXTURE_2D, m_iTextTexture); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); m_iTextTextureWidth = NextPow2(w); m_iTextTextureHeight = NextPow2(h); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_iTextTextureWidth, m_iTextTextureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_ALPHA, GL_UNSIGNED_BYTE, e); delete [] e; } if(m_iTextTexture) { /* draw texture with text */ glBindTexture(GL_TEXTURE_2D, m_iTextTexture); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glColor3ub(m_FontColor.Red(), m_FontColor.Green(), m_FontColor.Blue()); int x = r.x + m_NameLocationOffsetX, y = r.y + m_NameLocationOffsetY; float u = (float)w/m_iTextTextureWidth, v = (float)h/m_iTextTextureHeight; glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(x, y); glTexCoord2f(u, 0); glVertex2f(x+w, y); glTexCoord2f(u, v); glVertex2f(x+w, y+h); glTexCoord2f(0, v); glVertex2f(x, y+h); glEnd(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } } // Draw waypoint radar rings if activated if( m_iWaypointRangeRingsNumber && m_bShowWaypointRangeRings ) { double factor = 1.00; if( m_iWaypointRangeRingsStepUnits == 1 ) // nautical miles factor = 1 / 1.852; factor *= m_fWaypointRangeRingsStep; double tlat, tlon; wxPoint r1; ll_gc_ll( m_lat, m_lon, 0, factor, &tlat, &tlon ); cc1->GetCanvasPointPix( tlat, tlon, &r1 ); double lpp = sqrt( pow( (double) (r.x - r1.x), 2) + pow( (double) (r.y - r1.y), 2 ) ); int pix_radius = (int) lpp; wxPen ppPen1( m_wxcWaypointRangeRingsColour, platform_pen_width ); wxBrush saveBrush = dc.GetBrush(); wxPen savePen = dc.GetPen(); dc.SetPen( ppPen1 ); dc.SetBrush( wxBrush( m_wxcWaypointRangeRingsColour, wxBRUSHSTYLE_TRANSPARENT ) ); for( int i = 1; i <= m_iWaypointRangeRingsNumber; i++ ) dc.StrokeCircle( r.x, r.y, i * pix_radius ); dc.SetPen( savePen ); dc.SetBrush( saveBrush ); } if( m_bBlink ) g_blink_rect = CurrentRect_in_DC; // also save for global blinker // This will be useful for fast icon redraws CurrentRect_in_DC.x = r.x + hilitebox.x; CurrentRect_in_DC.y = r.y + hilitebox.y; CurrentRect_in_DC.width = hilitebox.width; CurrentRect_in_DC.height = hilitebox.height; if( m_bBlink ) g_blink_rect = CurrentRect_in_DC; // also save for global blinker }
void Route::Draw( ocpnDC& dc, ViewPort &VP ) { if( m_nPoints == 0 ) return; if( m_bVisible && m_bRtIsSelected ) { dc.SetPen( *g_pRouteMan->GetSelectedRoutePen() ); dc.SetBrush( *g_pRouteMan->GetSelectedRouteBrush() ); } else if ( m_bVisible ) { int style = wxSOLID; int width = g_route_line_width; wxColour col; if( m_style != STYLE_UNDEFINED ) style = m_style; if( m_width != STYLE_UNDEFINED ) width = m_width; if( m_Colour == wxEmptyString ) { col = g_pRouteMan->GetRoutePen()->GetColour(); } else { for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) { if( m_Colour == ::GpxxColorNames[i] ) { col = ::GpxxColors[i]; break; } } } dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) ); dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxSOLID ) ); } if( m_bVisible && m_bRtIsActive ) { dc.SetPen( *g_pRouteMan->GetActiveRoutePen() ); dc.SetBrush( *g_pRouteMan->GetActiveRouteBrush() ); } wxPoint rpt1, rpt2; if ( m_bVisible ) DrawPointWhich( dc, 1, &rpt1 ); wxRoutePointListNode *node = pRoutePointList->GetFirst(); RoutePoint *prp1 = node->GetData(); node = node->GetNext(); if ( !m_bVisible && prp1->m_bKeepXRoute ) prp1->Draw( dc ); while( node ) { RoutePoint *prp2 = node->GetData(); if ( !m_bVisible && prp2->m_bKeepXRoute ) prp2->Draw( dc ); else if (m_bVisible) prp2->Draw( dc, &rpt2 ); if ( m_bVisible ) { // Handle offscreen points bool b_2_on = VP.GetBBox().PointInBox( prp2->m_lon, prp2->m_lat, 0 ); bool b_1_on = VP.GetBBox().PointInBox( prp1->m_lon, prp1->m_lat, 0 ); //TODO This logic could be simpliifed //Simple case if( b_1_on && b_2_on ) RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x, rpt2.y, VP, true ); // with arrows // In the cases where one point is on, and one off // we must decide which way to go in longitude // Arbitrarily, we will go the shortest way double pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * VP.view_scale_ppm; double dp = pow( (double) ( rpt1.x - rpt2.x ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); double dtest; int adder; if( b_1_on && !b_2_on ) { if( rpt2.x < rpt1.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; dtest = pow( (double) ( rpt1.x - ( rpt2.x + adder ) ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x + adder, rpt2.y, VP, true ); } else if( !b_1_on && b_2_on ) { if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; dtest = pow( (double) ( rpt2.x - ( rpt1.x + adder ) ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, VP, true ); } //Both off, need to check shortest distance else if( !b_1_on && !b_2_on ) { if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; dtest = pow( (double) ( rpt2.x - ( rpt1.x + adder ) ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, VP, true ); } } rpt1 = rpt2; prp1 = prp2; node = node->GetNext(); } }
void Route::DrawGLLines( ViewPort &vp, ocpnDC *dc ) { #ifdef ocpnUSE_GL float pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * vp.view_scale_ppm; bool r1valid = false; wxPoint2DDouble r1; wxPoint2DDouble lastpoint; wxRoutePointListNode *node = pRoutePointList->GetFirst(); RoutePoint *prp2 = node->GetData(); cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &lastpoint); if(GetnPoints() == 1 && dc) { // single point.. make sure it shows up for highlighting cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r1); dc->DrawLine(r1.m_x, r1.m_y, r1.m_x+2, r1.m_y+2); return; } // Handle offscreen points LLBBox bbox = vp.GetBBox(); // dc is passed for thicker highlighted lines (performance not very important) if( !dc ) glBegin(GL_LINES); for(node = node->GetNext(); node; node = node->GetNext()) { RoutePoint *prp1 = prp2; prp2 = node->GetData(); // Provisional, to properly set status of last point in route prp2->m_pos_on_screen = false; { wxPoint2DDouble r2; cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r2); if(wxIsNaN(r2.m_x)) { r1valid = false; continue; } lastpoint = r2; // For active track segment to ownship // don't need to perform calculations or render segment // if both points are past any edge of the vp // TODO: use these optimizations for dc mode bool lat1l = prp1->m_lat < bbox.GetMinLat(), lat2l = prp2->m_lat < bbox.GetMinLat(); bool lat1r = prp1->m_lat > bbox.GetMaxLat(), lat2r = prp2->m_lat > bbox.GetMaxLat(); if( (lat1l && lat2l) || (lat1r && lat2r) ) { r1valid = false; prp1->m_pos_on_screen = false; continue; } bool lon1l, lon1r, lon2l, lon2r; TestLongitude(prp1->m_lon, bbox.GetMinLon(), bbox.GetMaxLon(), lon1l, lon1r); TestLongitude(prp2->m_lon, bbox.GetMinLon(), bbox.GetMaxLon(), lon2l, lon2r); if( (lon1l && lon2l) || (lon1r && lon2r) ) { r1valid = false; prp1->m_pos_on_screen = false; continue; } if(!r1valid) { cc1->GetDoubleCanvasPointPix( prp1->m_lat, prp1->m_lon, &r1); if(wxIsNaN(r1.m_x)) continue; } // we must decide which way to go in longitude // for projections which wrap, in this case, we will render two lines // (one may often be off screen which would be nice to fix but complicate things here // anyway, in some cases both points are on screen, but the route wraps to either side // so two lines are needed to draw this properly double adder = 0; if( (vp.m_projection_type == PROJECTION_MERCATOR || vp.m_projection_type == PROJECTION_EQUIRECTANGULAR) ) { float olon = vp.clon > 0 ? vp.clon - 180 : vp.clon + 180; if(prp1->m_lon < prp2->m_lon) { if(prp2->m_lon - prp1->m_lon < 180) { if(olon > prp1->m_lon && olon < prp2->m_lon) adder = pix_full_circle; } else if(olon < prp1->m_lon || olon > prp2->m_lon) adder = -pix_full_circle; } else if(prp1->m_lon - prp2->m_lon < 180) { if(olon < prp1->m_lon && olon > prp2->m_lon) adder = -pix_full_circle; } else if(olon > prp1->m_lon || olon < prp2->m_lon) adder = pix_full_circle; } if( dc ) if(adder) { float adderc = cos(vp.rotation)*adder, adders = sin(vp.rotation)*adder; dc->DrawLine(r1.m_x, r1.m_y, r2.m_x + adderc, r2.m_y + adders); dc->DrawLine(r1.m_x - adderc, r1.m_y - adders, r2.m_x, r2.m_y); } else dc->DrawLine(r1.m_x, r1.m_y, r2.m_x, r2.m_y); else { glVertex2f(r1.m_x, r1.m_y); if(adder) { float adderc = cos(vp.rotation)*adder, adders = sin(vp.rotation)*adder; glVertex2f(r2.m_x+adderc, r2.m_y+adders); glVertex2f(r1.m_x-adderc, r1.m_y-adders); } glVertex2f(r2.m_x, r2.m_y); // cache screen position for arrows and points if(!r1valid) { prp1->m_pos_on_screen = !lat1l && !lat1r && !lon1l && !lon1r; prp1->m_screen_pos = r1; } prp2->m_pos_on_screen = !lat2l && !lat2r && !lon2l && !lon2r; prp2->m_screen_pos = r2; } r1 = r2; r1valid = true; } } if( !dc ) glEnd(); #endif }
void Route::Draw( ocpnDC& dc, ViewPort &vp, const LLBBox &box ) { if( pRoutePointList->empty() ) return; LLBBox test_box = GetBBox(); if( box.IntersectOut( test_box ) ) // Route is wholly outside window return; int width = g_route_line_width; if( m_width != WIDTH_UNDEFINED ) width = m_width; if( m_bVisible && m_bRtIsSelected ) { wxPen spen = *g_pRouteMan->GetSelectedRoutePen(); spen.SetWidth( width ); dc.SetPen( spen ); dc.SetBrush( *g_pRouteMan->GetSelectedRouteBrush() ); } else if ( m_bVisible ) { wxPenStyle style = wxPENSTYLE_SOLID; wxColour col; if( m_style != wxPENSTYLE_INVALID ) style = m_style; if( m_Colour == wxEmptyString ) { col = g_pRouteMan->GetRoutePen()->GetColour(); } else { for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) { if( m_Colour == ::GpxxColorNames[i] ) { col = ::GpxxColors[i]; break; } } } dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) ); dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxBRUSHSTYLE_SOLID ) ); } if( m_bVisible && m_bRtIsActive ) { wxPen spen = *g_pRouteMan->GetActiveRoutePen(); spen.SetWidth( width ); dc.SetPen( spen ); dc.SetBrush( *g_pRouteMan->GetActiveRouteBrush() ); } wxPoint rpt1, rpt2; if ( m_bVisible ) DrawPointWhich( dc, 1, &rpt1 ); wxRoutePointListNode *node = pRoutePointList->GetFirst(); RoutePoint *prp1 = node->GetData(); node = node->GetNext(); if ( !m_bVisible && prp1->m_bKeepXRoute ) prp1->Draw( dc ); while( node ) { RoutePoint *prp2 = node->GetData(); if ( !m_bVisible && prp2->m_bKeepXRoute ) prp2->Draw( dc ); else if (m_bVisible) prp2->Draw( dc, &rpt2 ); if ( m_bVisible ) { // Handle offscreen points bool b_2_on = vp.GetBBox().Contains( prp2->m_lat, prp2->m_lon ); bool b_1_on = vp.GetBBox().Contains( prp1->m_lat, prp1->m_lon ); //Simple case if( b_1_on && b_2_on ) RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x, rpt2.y, vp, true, m_hiliteWidth ); // with arrows // In the cases where one point is on, and one off // we must decide which way to go in longitude // Arbitrarily, we will go the shortest way double pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * vp.view_scale_ppm; double dp = pow( (double) ( rpt1.x - rpt2.x ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); double dtest; int adder; if( b_1_on && !b_2_on ) { if( rpt2.x < rpt1.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; dtest = pow( (double) ( rpt1.x - ( rpt2.x + adder ) ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 ); if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x + adder, rpt2.y, vp, true, m_hiliteWidth ); } else if( !b_1_on ) { if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle; else adder = -(int) pix_full_circle; float rxd = rpt2.x - ( rpt1.x + adder ); float ryd = rpt1.y - rpt2.y; dtest = rxd*rxd + ryd*ryd; if( dp < dtest ) adder = 0; RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, vp, true, m_hiliteWidth ); } } rpt1 = rpt2; prp1 = prp2; node = node->GetNext(); } }
void Route::DrawGLLines( ViewPort &VP, ocpnDC *dc ) { #ifdef ocpnUSE_GL float pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * VP.view_scale_ppm; bool r1valid = false; wxPoint2DDouble r1; wxPoint2DDouble lastpoint; wxRoutePointListNode *node = pRoutePointList->GetFirst(); RoutePoint *prp2 = node->GetData(); cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &lastpoint); if(m_nPoints == 1 && dc) { // single point.. make sure it shows up for highlighting cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r1); dc->DrawLine(r1.m_x, r1.m_y, r1.m_x+2, r1.m_y+2); return; } // dc is passed for thicker highlighted lines (performance not very important) if( !dc ) glBegin(GL_LINES); unsigned short int FromSegNo = prp2->m_GPXTrkSegNo; for(node = node->GetNext(); node; node = node->GetNext()) { RoutePoint *prp1 = prp2; prp2 = node->GetData(); unsigned short int ToSegNo = prp2->m_GPXTrkSegNo; // Provisional, to properly set status of last point in route prp2->m_pos_on_screen = false; if (FromSegNo != ToSegNo) { FromSegNo = ToSegNo; r1valid = false; } else { wxPoint2DDouble r2; cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r2); lastpoint = r2; // For active track segment to ownship // Handle offscreen points LLBBox bbox = VP.GetBBox(); // don't need to perform calculations or render segment // if both points are past any edge of the vp // TODO: use these optimizations for dc mode bool lat1l = prp1->m_lat < bbox.GetMinY(), lat2l = prp2->m_lat < bbox.GetMinY(); bool lat1r = prp1->m_lat > bbox.GetMaxY(), lat2r = prp2->m_lat > bbox.GetMaxY(); if( (lat1l && lat2l) || (lat1r && lat2r) ) { r1valid = false; prp1->m_pos_on_screen = false; continue; } bool lon1l, lon1r, lon2l, lon2r; TestLongitude(prp1->m_lon, bbox.GetMinX(), bbox.GetMaxX(), lon1l, lon1r); TestLongitude(prp2->m_lon, bbox.GetMinX(), bbox.GetMaxX(), lon2l, lon2r); if( (lon1l && lon2l) || (lon1r && lon2r) ) { r1valid = false; prp1->m_pos_on_screen = false; continue; } if(!r1valid) cc1->GetDoubleCanvasPointPix( prp1->m_lat, prp1->m_lon, &r1); // In the cases where one point is on, and one off // we must decide which way to go in longitude double adder1 = 0, adder2 = 0; if(!(lon1l || lon1r) && (lon2l || lon2r) ) { // first point is on screen, second not if( r2.m_x < r1.m_x ) adder2 = pix_full_circle; else adder2 = -pix_full_circle; if( fabs(r1.m_x - r2.m_x) < fabs(r1.m_x - ( r2.m_x + adder2 )) ) adder2 = 0; } else if(lon1l || lon1r) { // first point is off screen if( r1.m_x < r2.m_x ) adder1 = pix_full_circle; else adder1 = -pix_full_circle; if( fabs(r1.m_x - r2.m_x) < fabs(r2.m_x - (r1.m_x + adder1)) ) adder1 = 0; } if( dc ) dc->DrawLine(r1.m_x + adder1, r1.m_y, r2.m_x + adder2, r2.m_y); else { glVertex2f(r1.m_x + adder1, r1.m_y); glVertex2f(r2.m_x + adder2, r2.m_y); // cache screen position for arrows and points if(!r1valid) { prp1->m_pos_on_screen = !lat1l && !lat1r && !lon1l && !lon1r; prp1->m_screen_pos = r1; } prp2->m_pos_on_screen = !lat2l && !lat2r && !lon2l && !lon2r; prp2->m_screen_pos = r2; } r1 = r2; r1valid = true; } } // Draw tentative segment from last point to Ownship, if running. if( IsTrack() ) { /* Active tracks */ if( dynamic_cast<Track *>(this)->IsRunning() ){ wxPoint2DDouble rs; cc1->GetDoubleCanvasPointPix( gLat, gLon, &rs); if( dc ) dc->DrawLine(lastpoint.m_x, lastpoint.m_y, rs.m_x, rs.m_y); else { glVertex2f(lastpoint.m_x, lastpoint.m_y); glVertex2f(rs.m_x, rs.m_y); } } } if( !dc ) glEnd(); #endif }
bool ViewPort::Divisor::Divide(ViewPort &Divisor, const double &Size) { // Add a new window to the split. return Divide(Divisor.GetFinalDivisor(), Size); }
void WVSChart::RenderViewOnDC(wxMemoryDC& dc, ViewPort& VPoint) { float *platray = NULL; float *plonray = NULL; int *psegray = NULL; int x,y; if(!m_ok) return; // Set Color wxPen *pthispen = wxThePenList->FindOrCreatePen(GetGlobalColor(_T("BLUE3")), 1, wxSOLID); dc.SetPen(*pthispen); // Compute the 1 degree cell boundaries int lat_min = (int)floor(VPoint.GetBBox().GetMinY()); int lat_max = (int)ceil(VPoint.GetBBox().GetMaxY()); int lon_min = (int)floor(VPoint.GetBBox().GetMinX()); int lon_max = (int)ceil(VPoint.GetBBox().GetMaxX()); x = lon_min; y = lat_min; // printf("%d %d\n", lon_min, lon_max); // Make positive definite longitude for easier integer math lon_min += 720; lon_max += 720; double ref_lon = VPoint.clon; // Loop around the lat/lon spec to get and draw the vector segments for(y = lat_min ; y < lat_max ; y++) { for(x = lon_min ; x < lon_max ; x++) { // Get the arrays of lat/lon vector segments // Sanity Check int xt = x; int yt = y; // Check the cache first int ix = xt % 360; //xt + 180; // bias to positive int iy = yt + 90; if( (ix > 359) || (ix < 0) || (iy > 179) || (iy < 0) ) continue; if(-1 == nseg[ix][iy]) // no data yet { // so fill cache platray = NULL; plonray = NULL; psegray = NULL; int nsegments = wvsrtv (*pwvs_file_name, y, ix, &platray, &plonray, &psegray); plat_ray[ix][iy] = platray; plon_ray[ix][iy] = plonray; pseg_ray[ix][iy] = psegray; nseg[ix][iy] = nsegments; // printf("load at %d %d \n", ix, iy); } // else // printf(" from cache at %d %d \n", ix, iy); if(nseg[ix][iy]) { float *plat_seg = plat_ray[ix][iy]; float *plon_seg = plon_ray[ix][iy]; int *pseg_cnt = pseg_ray[ix][iy]; for(int iseg = 0 ; iseg < nseg[ix][iy] ; iseg++) { int seg_cnt = *pseg_cnt++; if(seg_cnt > cur_seg_cnt_max) { cur_seg_cnt_max = seg_cnt; ptp = (wxPoint *)realloc(ptp, seg_cnt * sizeof(wxPoint)); } wxPoint *pr = ptp; wxPoint p; for(int ip = 0 ; ip < seg_cnt ; ip++) { float plat = *plat_seg++; float plon = *plon_seg++; if(fabs(plon - ref_lon) > 180.) { if(plon > ref_lon) plon -= 360.; else plon += 360.; } double easting, northing; toSM(plat, plon + 360., VPoint.clat, ref_lon + 360., &easting, &northing); double epix = easting * VPoint.view_scale_ppm; double npix = northing * VPoint.view_scale_ppm; double dx = epix * cos(VPoint.skew) + npix * sin(VPoint.skew); double dy = npix * cos(VPoint.skew) - epix * sin(VPoint.skew); p.x = (int)round((VPoint.pix_width / 2) + dx); p.y = (int)round((VPoint.pix_height / 2) - dy); *pr = p; pr++; } dc.DrawLines(seg_cnt, ptp); } } } // for x } //for y platray = NULL; plonray = NULL; psegray = NULL; wvsrtv (_T("clean"), y, x, &platray, &plonray, &psegray); }