/* *-------------------------------------------------------------------------------- * 函数名 : CreatePos * 功能 : 计算出轨迹上所有点的集合,保存到列表中去 * 参数 : VOID * 算法 : 通过 LineDDA 函数得出所有的轨迹点座标 * 前置条件 : 必须已经设定了轨迹起始点座标和终止点座标 * 后置条件 : 在 m_listTrackPoints 列表中保存所有轨迹点的座标 *-------------------------------------------------------------------------------- */ BOOL CRectangleTrack::CreatePos() { if (m_ptTrackStartPoint.y == m_ptTrackEndPoint.y && m_ptTrackStartPoint.x == m_ptTrackEndPoint.x) { // 水平线或是垂直线 LineDDA(m_ptTrackStartPoint.x, m_ptTrackStartPoint.y, m_ptTrackEndPoint.x, m_ptTrackEndPoint.y, CTrack::AddPosToList, (LPARAM) this); } else { CPoint ptVertex[4]; ptVertex[0] = m_ptTrackStartPoint; ptVertex[1].x = m_ptTrackEndPoint.x; ptVertex[1].y = m_ptTrackStartPoint.y; ptVertex[2] = m_ptTrackEndPoint; ptVertex[3].x = m_ptTrackStartPoint.x; ptVertex[3].y = m_ptTrackEndPoint.y; // 将矩形的四个顶点依次连线用 LineDDA 得到轨迹点 LineDDA(ptVertex[0].x, ptVertex[0].y, ptVertex[1].x, ptVertex[1].y, CTrack::AddPosToList, (LPARAM) this); LineDDA(ptVertex[1].x, ptVertex[1].y, ptVertex[2].x, ptVertex[2].y, CTrack::AddPosToList, (LPARAM) this); LineDDA(ptVertex[2].x, ptVertex[2].y, ptVertex[3].x, ptVertex[3].y, CTrack::AddPosToList, (LPARAM) this); LineDDA(ptVertex[3].x, ptVertex[3].y, ptVertex[0].x, ptVertex[0].y, CTrack::AddPosToList, (LPARAM) this); } return TRUE; }
/* *-------------------------------------------------------------------------------- * 函数名 : CreatePos * 功能 : 计算出轨迹上所有点的集合,保存到列表中去 * 参数 : VOID * 算法 : 通过 LineDDA 函数得出所有的轨迹点座标 * 前置条件 : 必须已经设定了轨迹起始点座标和终止点座标 * 后置条件 : 在 m_listTrackPoints 列表中保存所有轨迹点的座标 *-------------------------------------------------------------------------------- */ BOOL CRandomTrack::CreatePos() { // 两次鼠标移动事件有时间间隔 LineDDA(m_ptTrackStartPoint.x, m_ptTrackStartPoint.y, m_ptTrackEndPoint.x, m_ptTrackEndPoint.y, CTrack::AddPosToList, (LPARAM) this); return TRUE; }
/* *-------------------------------------------------------------------------------- * 函数名: CreatePos * 功能 : 计算出椭圆轨迹上所有点的集合,保存到列表中去 * 算法 : 根据椭圆方程求椭圆上的每一个点 * 前置条件: 必须已经设定了轨迹起始点座标和终止点座标 * 后置条件: 在 m_listTrackPoints 列表中保存所有轨迹点的座标 *-------------------------------------------------------------------------------- */ BOOL CEllipseTrack::CreatePos() { if (m_ptTrackStartPoint.y == m_ptTrackEndPoint.y && m_ptTrackStartPoint.x == m_ptTrackEndPoint.x) { // 水平线或是垂直线 LineDDA(m_ptTrackStartPoint.x, m_ptTrackStartPoint.y, m_ptTrackEndPoint.x, m_ptTrackEndPoint.y, CTrack::AddPosToList, (LPARAM) this); } else { int xCenter, yCenter; double a, b; xCenter = (m_ptTrackEndPoint.x + m_ptTrackStartPoint.x) / 2; yCenter = (m_ptTrackEndPoint.y + m_ptTrackStartPoint.y) / 2; // 椭圆 X 轴长度 a = abs(m_ptTrackEndPoint.x - m_ptTrackStartPoint.x) / 2; // 椭圆 Y 轴长度 b = abs(m_ptTrackEndPoint.y - m_ptTrackStartPoint.y) / 2; double b2 = b * b; double a2 = a * a; // 中心点为(xCenter, yCenter),扫描 X 轴求 Y 值 int x, y; for (x = (int) -a; x <= (int) a; x++) { y = (int) sqrt(b2 - (b2 / a2) * (x * x)); AddPoint(x + xCenter, y + yCenter); } // 求对称轴,求两次是为了让坐标是连贯的 for (x = (int) -a; x <= (int) a; x++) { y = (int) sqrt(b2 - (b2 / a2) * (x * x)); AddPoint(x + xCenter, yCenter - y); } // 中心点为(xCenter, yCenter),扫描 Y 轴求 X 值 for (y = (int) b; y >= (int) -b; y--) { x = (int) sqrt(a2 - (a2 / b2) * (y * y)); if ( y != (int) sqrt(b2 - (b2 / a2) * (x * x)) ) { AddPoint(xCenter - x, yCenter + y); } } // 求对称轴,求两次是为了让坐标是连贯的 for (y = (int) -b; y <= (int) b; y++) { x = (int) sqrt(a2 - (a2 / b2) * (y * y)); if ( y != (int) sqrt(b2 - (b2 / a2) * (x * x)) ) { AddPoint(x + xCenter, y + yCenter); } } } return TRUE; }
/* *-------------------------------------------------------------------------------- * 函数名 : CreatePos * 功能 : 计算出轨迹上所有点的集合,保存到列表中去 * 算法 : 由五角星的外部五个顶点和内部五个顶点依次连线, * 能过 LineDDA 函数得出所有的轨迹点座标 * 前置条件 : 必须已经设定了轨迹起始点座标和终止点座标 * 后置条件 : 在 m_listTrackPoints 列表中保存所有轨迹点的座标 *-------------------------------------------------------------------------------- */ BOOL CFiveSideTrack::CreatePos() { CPoint ptOutVertex[5]; // 五等分圆,得到五个顶点座标 SplitCircle(m_ptTrackStartPoint, m_ptTrackEndPoint, 5, ptOutVertex); // 将五边形的外部五顶点依次连线用 LineDDA 得到轨迹点 LineDDA(ptOutVertex[0].x, ptOutVertex[0].y, ptOutVertex[1].x, ptOutVertex[1].y, CTrack::AddPosToList, (LPARAM) this); LineDDA(ptOutVertex[1].x, ptOutVertex[1].y, ptOutVertex[2].x, ptOutVertex[2].y, CTrack::AddPosToList, (LPARAM) this); LineDDA(ptOutVertex[2].x, ptOutVertex[2].y, ptOutVertex[3].x, ptOutVertex[3].y, CTrack::AddPosToList, (LPARAM) this); LineDDA(ptOutVertex[3].x, ptOutVertex[3].y, ptOutVertex[4].x, ptOutVertex[4].y, CTrack::AddPosToList, (LPARAM) this); LineDDA(ptOutVertex[4].x, ptOutVertex[4].y, ptOutVertex[0].x, ptOutVertex[0].y, CTrack::AddPosToList, (LPARAM) this); return TRUE; }
void MainWindow::Paint( void ) { PAINTSTRUCT ps; RECT rect; LINEDDAPROC lpLineFunc; lpLineFunc = (LINEDDAPROC)MakeProcInstance( (FARPROC) MainWindow::LineFunc, Main::hInstance ); GetClientRect( hWnd, (LPRECT) &rect ); BeginPaint( hWnd, &ps ); LINEFUNCDATA LineFuncData( ps.hdc, lpBitmap1, lpBitmap2 ); LineDDA( 0, 0, rect.right - (lpBitmap1->GetSize( ps.hdc )).x, 0, lpLineFunc, (LPARAM)&LineFuncData ); EndPaint( hWnd, &ps ); FreeProcInstance((FARPROC)lpLineFunc ); }
void CDemoView::DrawSelection() { CDemoDoc* pDoc = GetDocument(); if (pDoc->m_NumSel>2){ CPoint pos(GetScrollPosition()); float zoom=pDoc->GetZoomFactor(); m_SelCount=m_SelShift; // pDC->MoveTo(zoom*pDoc->m_Sel[0].x - pos.x,zoom*pDoc->m_Sel[0].y - pos.y); for(int i=1;i<pDoc->m_NumSel;i++){ // pDC->LineTo(zoom*pDoc->m_Sel[i].x - pos.x,zoom*pDoc->m_Sel[i].y - pos.y); LineDDA((int)(zoom*pDoc->m_Sel[i-1].x - pos.x), (int)(zoom*pDoc->m_Sel[i-1].y - pos.y), (int)(zoom*pDoc->m_Sel[i].x - pos.x), (int)(zoom*pDoc->m_Sel[i].y - pos.y), (LINEDDAPROC)LineDDAProc,(LPARAM)this); } } }
/* * "shoot" a bolt from the current bolt location to the "aim" location */ static void ShootBolt( HWND window_handle ) /*****************************************/ { extra_data *edata_ptr; HDC hdc; HBITMAP screensavebmp; MSG msg; FARPROC proc; HANDLE inst_handle; icon_mover mover; edata_ptr = (extra_data *) GetWindowLong( window_handle, EXTRA_DATA_OFFSET ); hdc = GetDC( window_handle ); inst_handle = GetWindowWord( window_handle, GWW_HINSTANCE ); /* set up an "icon_mover" struct to give all needed data to DrawBolt */ mover.icon = edata_ptr->bolt_icon; mover.size.x = BOLTWIDTH; mover.size.y = BOLTHEIGHT; mover.last.x = -1; mover.last.y = -1; mover.screen_dc = hdc; mover.storage_dc = CreateCompatibleDC( hdc ); mover.speed = edata_ptr->bolt_speed; screensavebmp = CreateCompatibleBitmap( hdc, mover.size.x, mover.size.y ); SelectObject( mover.storage_dc, screensavebmp ); if( edata_ptr->sound_on ) { BoltSound(); } /* * for each point on the line between the points BOLT and AIM, * call DrawBolt * use aim - boltheight so that the bottom left corner of the bolt icon * stops at the point AIM */ proc = MakeProcInstance( (FARPROC)DrawBolt, inst_handle ); LineDDA( edata_ptr->bolt.x, edata_ptr->bolt.y, edata_ptr->aim.x, edata_ptr->aim.y - BOLTHEIGHT, proc, (LPARAM)(LPVOID)&mover ); FreeProcInstance( proc ); /* * remove all WM_LBUTTONDOWN messages from the application queue which * occured while the bolt was "in the air" * this prevents the shots from building up - only 1 can happen at a time */ while( PeekMessage( &msg, window_handle, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE ) ); /* make sure the bolt is drawn at the final location regardless of speed */ mover.speed = 1; DoDrawBolt( edata_ptr->aim.x, edata_ptr->aim.y - BOLTHEIGHT, &mover ); if( edata_ptr->sound_on ) { BoomSound(); } /* redraw the background behind the icon */ BitBlt( mover.screen_dc, mover.last.x, mover.last.y, mover.size.x, mover.size.y, mover.storage_dc, 0, 0, SRCCOPY); CheckHit( hdc, edata_ptr->aim ); DeleteDC( mover.storage_dc ); DeleteObject( screensavebmp ); ReleaseDC(window_handle, hdc); } /* ShootBolt */
static void test_linedda(void) { const POINT *pt; static const POINT array_10_20_20_40[] = {{10,20},{10,21},{11,22},{11,23}, {12,24},{12,25},{13,26},{13,27}, {14,28},{14,29},{15,30},{15,31}, {16,32},{16,33},{17,34},{17,35}, {18,36},{18,37},{19,38},{19,39}, {-1,-1}}; static const POINT array_10_20_20_43[] = {{10,20},{10,21},{11,22},{11,23}, {12,24},{12,25},{13,26},{13,27}, {13,28},{14,29},{14,30},{15,31}, {15,32},{16,33},{16,34},{17,35}, {17,36},{17,37},{18,38},{18,39}, {19,40},{19,41},{20,42},{-1,-1}}; static const POINT array_10_20_10_20[] = {{-1,-1}}; static const POINT array_10_20_11_27[] = {{10,20},{10,21},{10,22},{10,23}, {11,24},{11,25},{11,26},{-1,-1}}; static const POINT array_20_43_10_20[] = {{20,43},{20,42},{19,41},{19,40}, {18,39},{18,38},{17,37},{17,36}, {17,35},{16,34},{16,33},{15,32}, {15,31},{14,30},{14,29},{13,28}, {13,27},{13,26},{12,25},{12,24}, {11,23},{11,22},{10,21},{-1,-1}}; static const POINT array_20_20_10_43[] = {{20,20},{20,21},{19,22},{19,23}, {18,24},{18,25},{17,26},{17,27}, {17,28},{16,29},{16,30},{15,31}, {15,32},{14,33},{14,34},{13,35}, {13,36},{13,37},{12,38},{12,39}, {11,40},{11,41},{10,42},{-1,-1}}; static const POINT array_20_20_43_10[] = {{20,20},{21,20},{22,19},{23,19}, {24,18},{25,18},{26,17},{27,17}, {28,17},{29,16},{30,16},{31,15}, {32,15},{33,14},{34,14},{35,13}, {36,13},{37,13},{38,12},{39,12}, {40,11},{41,11},{42,10},{-1,-1}}; pt = array_10_20_20_40; LineDDA(10, 20, 20, 40, linedda_callback, (LPARAM)&pt); ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n"); pt = array_10_20_20_43; LineDDA(10, 20, 20, 43, linedda_callback, (LPARAM)&pt); ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n"); pt = array_10_20_10_20; LineDDA(10, 20, 10, 20, linedda_callback, (LPARAM)&pt); ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n"); pt = array_10_20_11_27; LineDDA(10, 20, 11, 27, linedda_callback, (LPARAM)&pt); ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n"); pt = array_20_43_10_20; LineDDA(20, 43, 10, 20, linedda_callback, (LPARAM)&pt); ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n"); pt = array_20_20_10_43; LineDDA(20, 20, 10, 43, linedda_callback, (LPARAM)&pt); ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n"); pt = array_20_20_43_10; LineDDA(20, 20, 43, 10, linedda_callback, (LPARAM)&pt); ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n"); }
void PASCAL _Cover_LineDDA( short x1, short y1, short x2, short y2, LINEDDAPROC p, LPARAM data ) { LineDDA( x1, y1, x2, y2, SetProc( (FARPROC)p, GETPROC_LINEDDA ), (LPARAM) data ); }