void CPage_Node_Phase::DrawMovements(CPaintDC* pDC,CRect PlotRect, bool bPhaseWindow =false) { m_MovementBezierVector.clear(); CPen NormalPen(PS_SOLID,2,RGB(0,0,0)); CPen TimePen(PS_DOT,1,RGB(0,0,0)); CPen DASHPen(PS_SOLID,1,RGB(255,178,102)); CPen DataPen(PS_SOLID,0,RGB(0,0,0)); CPen SelectedPen(PS_SOLID,3,RGB(255,0,0)); CPen SelectedPhasePen(PS_SOLID,4,RGB(0,0,255)); CBrush WhiteBrush(RGB(255,255,255)); pDC->SetBkMode(TRANSPARENT); pDC->SelectObject(&DataPen); pDC->SelectObject(&WhiteBrush); pDC->Rectangle (PlotRect); CString str; if(bPhaseWindow == true ) { str.Format("Phase %d",m_SelectedPhaseNumber); pDC->TextOutA(PlotRect.left+10,PlotRect.top +5,str); } CBrush BrushLinkBand(RGB(152,245,255)); pDC->SelectObject(&BrushLinkBand); DTANode* pNode = m_pDoc->m_NodeNoMap [m_CurrentNodeID]; int node_size = 10; int node_set_back = 50; int link_length = 100; int lane_width = 10; int text_length = link_length+ 20; str.Format("%d",m_CurrentNodeNumber); if(bPhaseWindow == false || m_SelectedPhaseNumber == 1) pDC->TextOutA( PlotRect.CenterPoint().x-5, PlotRect.CenterPoint().y-5,str); for (unsigned int i=0;i< pNode->m_MovementDataMap["ALLDAY"].m_MovementVector .size();i++) { DTANodeMovement movement = pNode->m_MovementDataMap["ALLDAY"].m_MovementVector[i]; if( m_pDoc->m_hide_non_specified_movement_on_freeway_and_ramp && movement.bNonspecifiedTurnDirectionOnFreewayAndRamps && i != m_SelectedMovementIndex) continue; DTALink* pInLink = m_pDoc->m_LinkNoMap [movement.IncomingLinkNo]; DTALink* pOutLink = m_pDoc->m_LinkNoMap [movement.OutgoingLinkNo ]; GDPoint p1, p2, p3; // 1: fetch all data p1 = m_pDoc->m_NodeNoMap[movement.in_link_from_node_id ]->pt; p2 = m_pDoc->m_NodeNoMap[movement.in_link_to_node_id ]->pt; p3 = m_pDoc->m_NodeNoMap[movement.out_link_to_node_id]->pt; double DeltaX = p2.x - p1.x ; double DeltaY = p2.y - p1.y ; double theta = atan2(DeltaY, DeltaX); GDPoint p1_new, p2_new, p3_new; GDPoint p1_text, p3_text; GDPoint pt_movement[3]; // 2. set new origin p2_new.x = (-1)*node_set_back*cos(theta); p2_new.y = (-1)*node_set_back*sin(theta); int link_mid_offset = (pInLink->m_NumberOfLanes/2 +1)*lane_width; // mid pt_movement[0].x = p2_new.x + link_mid_offset* cos(theta-PI/2.0f); pt_movement[0].y = p2_new.y + link_mid_offset* sin(theta-PI/2.0f); // 3 determine the control point for PolyBezier float control_point_ratio = 0; if(movement.movement_turn == DTA_Through ) { control_point_ratio = 0; }else if(movement.movement_turn == DTA_LeftTurn ) { control_point_ratio = 1.2; }else { control_point_ratio = 0.5; } pt_movement[1].x = pt_movement[0].x + node_set_back*control_point_ratio*cos(theta); pt_movement[1].y = pt_movement[0].y + node_set_back*control_point_ratio*sin(theta); if(bPhaseWindow == true) { link_length = 1; text_length = node_set_back+10; } p1_new.x = (-1)*link_length*cos(theta); p1_new.y = (-1)*link_length*sin(theta); p1_text.x= (-1)*(text_length)*cos(theta); p1_text.y= (-1)*(text_length)*sin(theta); // 4: draw from node name str.Format("%d",m_pDoc->m_NodeNoMap [movement.in_link_from_node_id]->m_NodeNumber ); if(p1_text.y < -50) p1_text.y +=10; CPoint pt_text = NPtoSP(p1_text); if(bPhaseWindow == false || m_SelectedPhaseNumber == 1) { pDC->SetTextColor(RGB(0,0,255)); pDC->TextOutA(pt_text.x-10,pt_text.y,str); pDC->SetTextColor(RGB(0,0,0)); } if(bPhaseWindow == false) DrawLink(pDC,p1_new,p2_new,pInLink->m_NumberOfLanes,theta,lane_width); //////////////////////////////////////////// //5: outgoing link DeltaX = p3.x - p2.x ; DeltaY = p3.y - p2.y ; theta = atan2(DeltaY, DeltaX); // set new origin p2_new.x = node_set_back*cos(theta); p2_new.y = node_set_back*sin(theta); link_mid_offset = (pOutLink->m_NumberOfLanes/2+1)*lane_width; pt_movement[2].x = p2_new.x + link_mid_offset* cos(theta-PI/2.0f); pt_movement[2].y = p2_new.y + link_mid_offset* sin(theta-PI/2.0f); p3_new.x = link_length*cos(theta); p3_new.y = link_length*sin(theta); p3_text.x= text_length*cos(theta); p3_text.y= text_length*sin(theta); if(bPhaseWindow == false) DrawLink(pDC,p2_new,p3_new,pOutLink->m_NumberOfLanes,theta,lane_width); DTALink * pRevLink = NULL; //reversed link unsigned long ReversedLinkKey = m_pDoc->GetLinkKey(pOutLink->m_ToNodeID, pOutLink->m_FromNodeID); int reversed_link_id = 0; if ( m_pDoc->m_NodeNotoLinkMap.find ( ReversedLinkKey) == m_pDoc->m_NodeNotoLinkMap.end()) { str.Format("%d",m_pDoc->m_NodeNoMap [movement.out_link_to_node_id ]->m_NodeNumber ); if(p3_text.y < -50) p3_text.y +=10; pt_text = NPtoSP(p3_text); if(bPhaseWindow == false || m_SelectedPhaseNumber == 1) pDC->TextOutA(pt_text.x-10,pt_text.y,str); } // draw movement CPoint Point_Movement[4]; if(i == m_SelectedMovementIndex) { pDC->SelectObject(&SelectedPen); } else { //if(m_ListCtrl.GetItemText (i,4).Find("Prohibited") != -1) // select prohibited movement pen: // pDC->SelectObject(&g_PenProhibitedMovement); //else // pDC->SelectObject(&NormalPen); } if(movement.movement_turn == DTA_LeftTurn ) { float weight = 0.9; pt_movement[1].x = (1-weight)*(pt_movement[0].x + pt_movement[2].x)/2 +0*weight; pt_movement[1].y = (1-weight)*(pt_movement[0].y + pt_movement[2].y)/2 +0*weight; } Point_Movement[0]= NPtoSP(pt_movement[0]); Point_Movement[1]= NPtoSP(pt_movement[1]); Point_Movement[2]= NPtoSP(pt_movement[1]); Point_Movement[3]= NPtoSP(pt_movement[2]); Point_Movement[0]= NPtoSP(pt_movement[0]); Point_Movement[1]= NPtoSP(pt_movement[1]); Point_Movement[2]= NPtoSP(pt_movement[1]); Point_Movement[3]= NPtoSP(pt_movement[2]); MovementBezier element(Point_Movement[0], Point_Movement[1],Point_Movement[3]); m_MovementBezierVector.push_back (element); if(m_bHideRightTurnMovement &&( pNode->m_MovementDataMap["ALLDAY"].m_MovementVector[i].movement_turn == DTA_RightTurn || pNode->m_MovementDataMap["ALLDAY"].m_MovementVector[i].movement_turn == DTA_RightTurn2)) continue; bool bMovementIncluded = false; if(m_SelectedPhaseNumber >=1) { bMovementIncluded = m_pDoc->IfMovementIncludedInPhase(m_CurrentNodeNumber ,m_pDoc->m_TimingPlanVector [ m_SelectedTimingPlanNo].timing_plan_name,m_SelectedPhaseNumber, movement.in_link_from_node_id,movement.out_link_to_node_id ); } if(m_SelectedPhaseNumber <=0 || /* all phases*/ m_SelectedPhaseNumber>=1 && ( bMovementIncluded == true || m_bPhasingDataEditMode) ) // seleted phase { pDC->SelectObject(&NormalPen); if(m_SelectedPhaseNumber>=1 && m_bPhasingDataEditMode) { if( bMovementIncluded == true) pDC->SelectObject(&NormalPen); else pDC->SelectObject(&DASHPen); } if(i == m_SelectedMovementIndex && m_bPhasingDataEditMode) { pDC->SelectObject(&SelectedPen); } //overwrite if(i == m_SelectedMovementIndex) { pDC->SelectObject(&SelectedPen); } pDC->PolyBezier(Point_Movement,4); bool bShowArrow = false; if(m_SelectedPhaseNumber>=1 && bMovementIncluded == true) { bShowArrow = true; } if(bShowArrow) { CPoint FromPoint = Point_Movement[2] ; CPoint ToPoint = Point_Movement[3]; CPoint arrow_pts[3]; double slopy = atan2((double)(FromPoint.y - ToPoint.y), (double)(FromPoint.x - ToPoint.x)); double cosy = cos(slopy); double siny = sin(slopy); double display_length = sqrt((double)(FromPoint.y - ToPoint.y)*(FromPoint.y - ToPoint.y)+(double)(FromPoint.x - ToPoint.x)*(FromPoint.x - ToPoint.x)); double arrow_size = min(10,display_length/3.0); if(arrow_size>0.2) { arrow_pts[0] = ToPoint; arrow_pts[1].x = ToPoint.x + (int)(arrow_size * cosy - (arrow_size / 2.0 * siny) + 0.5); arrow_pts[1].y = ToPoint.y + (int)(arrow_size * siny + (arrow_size / 2.0 * cosy) + 0.5); arrow_pts[2].x = ToPoint.x + (int)(arrow_size * cosy + arrow_size / 2.0 * siny + 0.5); arrow_pts[2].y = ToPoint.y - (int)(arrow_size / 2.0 * cosy - arrow_size * siny + 0.5); pDC->Polygon(arrow_pts, 3); } } } //restore pen pDC->SelectObject(&DataPen); } }
void CPage_Node_LaneTurn::DrawMovements(CPaintDC* pDC,CRect PlotRect) { m_MovementBezierVector.clear(); CPen NormalPen(PS_SOLID,2,RGB(0,0,0)); CPen TimePen(PS_DOT,1,RGB(0,0,0)); CPen DataPen(PS_SOLID,0,RGB(0,0,0)); CPen SelectedPen(PS_SOLID,4,RGB(255,0,0)); CPen SelectedPhasePen(PS_SOLID,4,RGB(0,0,255)); CBrush WhiteBrush(RGB(255,255,255)); pDC->SetBkMode(TRANSPARENT); pDC->SelectObject(&DataPen); pDC->SelectObject(&WhiteBrush); pDC->Rectangle (PlotRect); CBrush BrushLinkBand(RGB(152,245,255)); pDC->SelectObject(&BrushLinkBand); DTANode* pNode = m_pDoc->m_NodeIDMap [m_CurrentNodeID]; int node_size = 10; int node_set_back = 50; int link_length = 150; int lane_width = 10; int text_length = link_length+ 20; CString str; str.Format("%d",m_CurrentNodeName); pDC->TextOutA( PlotRect.CenterPoint().x-5, PlotRect.CenterPoint().y-5,str); for (unsigned int i=0;i< pNode->m_MovementVector .size();i++) { DTANodeMovement movement = pNode->m_MovementVector[i]; DTALink* pInLink = m_pDoc->m_LinkNoMap [movement.IncomingLinkID]; DTALink* pOutLink = m_pDoc->m_LinkNoMap [movement.OutgoingLinkID ]; GDPoint p1, p2, p3; // 1: fetch all data p1 = m_pDoc->m_NodeIDMap[movement.in_link_from_node_id ]->pt; p2 = m_pDoc->m_NodeIDMap[movement.in_link_to_node_id ]->pt; p3 = m_pDoc->m_NodeIDMap[movement.out_link_to_node_id]->pt; double DeltaX = p2.x - p1.x ; double DeltaY = p2.y - p1.y ; double theta = atan2(DeltaY, DeltaX); GDPoint p1_new, p2_new, p3_new; GDPoint p1_text, p3_text; GDPoint pt_movement[3]; // 2. set new origin p2_new.x = (-1)*node_set_back*cos(theta); p2_new.y = (-1)*node_set_back*sin(theta); int link_mid_offset = (pInLink->m_NumberOfLanes/2 +1)*lane_width; // mid pt_movement[0].x = p2_new.x + link_mid_offset* cos(theta-PI/2.0f); pt_movement[0].y = p2_new.y + link_mid_offset* sin(theta-PI/2.0f); // 3 determine the control point for PolyBezier float control_point_ratio = 0; if(movement.movement_turn == DTA_Through ) { control_point_ratio = 0; }else if(movement.movement_turn == DTA_LeftTurn ) { control_point_ratio = 1.2; }else { control_point_ratio = 0.5; } pt_movement[1].x = pt_movement[0].x + node_set_back*control_point_ratio*cos(theta); pt_movement[1].y = pt_movement[0].y + node_set_back*control_point_ratio*sin(theta); p1_new.x = (-1)*link_length*cos(theta); p1_new.y = (-1)*link_length*sin(theta); p1_text.x= (-1)*(text_length)*cos(theta); p1_text.y= (-1)*(text_length)*sin(theta); // 4: draw from node name str.Format("%d",m_pDoc->m_NodeIDtoNameMap [movement.in_link_from_node_id]); if(p1_text.y < -50) p1_text.y +=10; CPoint pt_text = NPtoSP(p1_text); pDC->TextOutA(pt_text.x-10,pt_text.y,str); DrawLink(pDC,p1_new,p2_new,pInLink->m_NumberOfLanes,theta,lane_width); //////////////////////////////////////////// //5: outgoing link DeltaX = p3.x - p2.x ; DeltaY = p3.y - p2.y ; theta = atan2(DeltaY, DeltaX); // set new origin p2_new.x = node_set_back*cos(theta); p2_new.y = node_set_back*sin(theta); link_mid_offset = (pOutLink->m_NumberOfLanes/2+1)*lane_width; pt_movement[2].x = p2_new.x + link_mid_offset* cos(theta-PI/2.0f); pt_movement[2].y = p2_new.y + link_mid_offset* sin(theta-PI/2.0f); p3_new.x = link_length*cos(theta); p3_new.y = link_length*sin(theta); p3_text.x= text_length*cos(theta); p3_text.y= text_length*sin(theta); //draw to node name str.Format("%d",m_pDoc->m_NodeIDtoNameMap [movement.out_link_to_node_id]); if(p3_text.y < -100) p3_text.y +=10; pt_text = NPtoSP(p3_text); pDC->TextOutA(pt_text.x-10 ,pt_text.y,str); DrawLink(pDC,p2_new,p3_new,pOutLink->m_NumberOfLanes,theta,lane_width); // draw movement CPoint Point_Movement[4]; if(i == m_SelectedMovementIndex) pDC->SelectObject(&SelectedPen); else pDC->SelectObject(&NormalPen); Point_Movement[0]= NPtoSP(pt_movement[0]); Point_Movement[1]= NPtoSP(pt_movement[1]); Point_Movement[2]= NPtoSP(pt_movement[1]); Point_Movement[3]= NPtoSP(pt_movement[2]); Point_Movement[0]= NPtoSP(pt_movement[0]); Point_Movement[1]= NPtoSP(pt_movement[1]); Point_Movement[2]= NPtoSP(pt_movement[1]); Point_Movement[3]= NPtoSP(pt_movement[2]); MovementBezier element(Point_Movement[0], Point_Movement[1],Point_Movement[3]); m_MovementBezierVector.push_back (element); pDC->PolyBezier(Point_Movement,4); //restore pen pDC->SelectObject(&DataPen); } }