Новичок
Профиль
Группа: Участник
Сообщений: 4
Регистрация: 7.12.2006
Репутация: нет Всего: нет
|
Проблема такая: Есть Приложение, вычисляющее точку оптимума функции по методу симплекса. объект вида - скроллинговый, причём размер больше размера экрана, то есть скролл нужен всегда. В главном окне в OnDraw рисуются координатные оси для трёх графиков. Также есть отдальный поток, рисующий сам процесс поиска методом симплекса (рисует наглядно, то есть шаг за шагом, по типу анимации). Собственно суть проблемы в том, что при любом скролле вниз координатная система для потока меняется и точка (0,0) совпадает с левым верхним углом ОТОБРАЖАЕМОЙ В ДАННЫЙ МОМЕНТ части объекта вида. А координатные оси остаются на своих местах. Соответственно следующий после прокрутки вниз шаг графика рисуется ниже чем надо. Как сделать так чтобы координаты для потока были постоянными и не зависили от скроллинга и отображаемой части объекта вида? Возможно ошибка в контексте устройства... Пожалуйста, подскажите что и где надо поменять\дописать... Также интересно, как сделать чтобы прис выходе за границу области где должен быть рисунок (когда сильно прокручиваешь вниз), графическая информация потока не стиралась а оставалась нарисованной. вот код потока и метода OnDraw: Код | ///////////////////////////////////////////////////////////////////////////////////////////////////
Объявление класса class CSimplexView : public CScrollView { protected: // create from serialization only CSimplexView(); DECLARE_DYNCREATE(CSimplexView)
// Attributes public: CSimplexDoc* GetDocument();
// Operations public: CClientDC *m_pDC; // óêàçàòåëü íà êîíòåêñò êëèåíòñêîé ÷àñòè îêíà CRITICAL_SECTION m_ClientDCLock; // êðèòè÷åñêàÿ ñåêöèÿ // int m_nThreadCounter; // ñ÷åò÷èê ÷èñëà çàïóùåííûõ ïîòîêîâ bool m_bWorking; int ViewCheck; // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CSimplexView) public: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual void OnInitialUpdate(); // called first time after construct virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); //}}AFX_VIRTUAL
// Implementation public: virtual ~CSimplexView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif
// SimplexView.cpp : implementation of the CSimplexView class //
#include "stdafx.h" #include "Simplex.h"
#include "SimplexDoc.h" #include "SimplexView.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
///////////////////////////////////////////////////////////////////////////// // CSimplexView
IMPLEMENT_DYNCREATE(CSimplexView, CScrollView)
BEGIN_MESSAGE_MAP(CSimplexView, CScrollView) //{{AFX_MSG_MAP(CSimplexView) ON_COMMAND(ID_VIEW_GRAPH, OnViewGraph) ON_COMMAND(ID_VIEW_TABLE, OnViewTable) ON_WM_CREATE() ON_WM_DESTROY() ON_UPDATE_COMMAND_UI(ID_VIEW_SEARCHPROCESS, OnUpdateViewSearchprocess) ON_COMMAND(ID_VIEW_SEARCHPROCESS, OnViewSearchprocess) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview) END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CSimplexView construction/destruction
CSimplexView::CSimplexView() { // TODO: add construction code here ViewCheck=0; m_pDC = 0; m_bWorking = false; // m_nThreadCounter = 0; InitializeCriticalSection(&m_ClientDCLock);
}
CSimplexView::~CSimplexView() { DeleteCriticalSection(&m_ClientDCLock); }
BOOL CSimplexView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs); }
///////////////////////////////////////////////////////////////////////////// // CSimplexView drawing
UINT SearchThread(LPVOID pParam) { CSimplexView* pView = (CSimplexView*)pParam; // ïðåîáðàçîâàíèå àðãóìåíòà ê óêàçàòåëþ íà îáúåêò âèäà CSimplexDoc* pDoc = pView->GetDocument(); // ASSERT_VALID(pDoc); pView->m_bWorking = true; int xmin=30, xmax=1030, ymin=30, ymax=1030; int morphX=(xmax-xmin)/5; int morphY=-morphX; CPen penlight(PS_SOLID, 1, RGB(230,230,230)); CPen pendark(PS_SOLID, 2, RGB(25,25,25)); CPen pengreen(PS_SOLID, 5, RGB(0,255,0)); CPen penbluefat(PS_SOLID, 5, RGB(0,0,255)); CPen penbluethin(PS_SOLID, 1, RGB(0,0,255)); for (int i=0;i<pDoc->Iter;i++) if (pView->ViewCheck==1) { EnterCriticalSection(&pView->m_ClientDCLock); pView->m_pDC->SelectObject(pengreen); pView->m_pDC->MoveTo(pDoc->X[i][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i][0][1]*morphY+(ymax+ymin)/2); pView->m_pDC->LineTo(pDoc->X[i][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i][0][1]*morphY+(ymax+ymin)/2);
pView->m_pDC->SelectObject(penlight); pView->m_pDC->LineTo(pDoc->X[i][1][0]*morphX+(xmax+xmin)/2, pDoc->X[i][1][1]*morphY+(ymax+ymin)/2); pView->m_pDC->LineTo(pDoc->X[i][2][0]*morphX+(xmax+xmin)/2, pDoc->X[i][2][1]*morphY+(ymax+ymin)/2); pView->m_pDC->LineTo(pDoc->X[i][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i][0][1]*morphY+(ymax+ymin)/2);
pView->m_pDC->SelectObject(penbluefat); pView->m_pDC->MoveTo(pDoc->X[i][pDoc->MaxF[i]][0]*morphX+(xmax+xmin)/2, pDoc->X[i][pDoc->MaxF[i]][1]*morphY+(ymax+ymin)/2); pView->m_pDC->LineTo(pDoc->X[i][pDoc->MaxF[i]][0]*morphX+(xmax+xmin)/2, pDoc->X[i][pDoc->MaxF[i]][1]*morphY+(ymax+ymin)/2); pView->m_pDC->SelectObject(penbluethin); pView->m_pDC->LineTo(pDoc->X[i+1][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i+1][0][1]*morphY+(ymax+ymin)/2); pView->m_pDC->SelectObject(penbluefat); pView->m_pDC->LineTo(pDoc->X[i+1][0][0]*morphX+(xmax+xmin)/2, pDoc->X[i+1][0][1]*morphY+(ymax+ymin)/2); GdiFlush(); LeaveCriticalSection(&pView->m_ClientDCLock);
Sleep(1000); } pView->m_pDC->SelectObject(pendark); for (i=0;i<pDoc->Iter-1;i++) if (pView->ViewCheck==1) { pView->m_pDC->MoveTo(pDoc->X[i][pDoc->MinF[i]][0]*morphX+(xmax+xmin)/2, pDoc->X[i][pDoc->MinF[i]][1]*morphY+(ymax+ymin)/2); pView->m_pDC->LineTo(pDoc->X[i+1][pDoc->MinF[i+1]][0]*morphX+(xmax+xmin)/2, pDoc->X[i+1][pDoc->MinF[i+1]][1]*morphY+(ymax+ymin)/2); } pView->m_bWorking = false; return 0; }
void CSimplexView::OnDraw(CDC* pDC) { CSimplexDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here TEXTMETRIC Metric; pDC->GetTextMetrics(&Metric); CString str; CSize size; if (ViewCheck==1) { CPen pen(PS_SOLID, 1, RGB(0,0,0)); pDC->SelectObject(pen); CSize NameSize; CString strName; CFont font; CFont* pOldFont = NULL; // óêàçàòåëü íà ðàíåå èñïîëüçóåìûé øðèôò // int xmin[3]={30,30,560}, xmax[3]={530,530,1060}, ymin[3]={30,560,30}, ymax[3]={530,1060,530}; int xmin[3]={30,30,30}, xmax[3]={1030,1030,1030}, ymin[3]={2090,1060,30}, ymax[3]={3090,2060,1030}; int morphX=(xmax[1]-xmin[1])/5; int morphY=-morphX; if(font.CreateFontIndirect(&pDoc->m_logFont)) pOldFont=pDC->SelectObject(&font);
//Ñèñòåìà êîîðäèíàò //îêíà for (int i=0;i<3;i++) { pDC->MoveTo(xmin[i]-5,ymin[i]-5); pDC->LineTo(xmax[i]+5,ymin[i]-5); pDC->LineTo(xmax[i]+5,ymax[i]+5); pDC->LineTo(xmin[i]-5,ymax[i]+5); pDC->LineTo(xmin[i]-5,ymin[i]-5); pDC->MoveTo(xmin[i]-10,ymin[i]-10); pDC->LineTo(xmax[i]+10,ymin[i]-10); pDC->LineTo(xmax[i]+10,ymax[i]+10); pDC->LineTo(xmin[i]-10,ymax[i]+10); pDC->LineTo(xmin[i]-10,ymin[i]-10); }
//îñè äëÿ òðàåêòîðèè i=2; pDC->MoveTo((xmax[i]+xmin[i])/2,ymin[i]); pDC->LineTo((xmax[i]+xmin[i])/2+3,ymin[i]+10); pDC->MoveTo((xmax[i]+xmin[i])/2,ymin[i]); pDC->LineTo((xmax[i]+xmin[i])/2-3,ymin[i]+10); pDC->MoveTo((xmax[i]+xmin[i])/2,ymin[i]); pDC->LineTo((xmax[i]+xmin[i])/2,ymax[i]); pDC->MoveTo(xmin[i],(ymax[i]+ymin[i])/2); pDC->LineTo(xmax[i],(ymax[i]+ymin[i])/2); pDC->LineTo(xmax[i]-10,(ymax[i]+ymin[i])/2+3); pDC->MoveTo(xmax[i],(ymax[i]+ymin[i])/2); pDC->LineTo(xmax[i]-10,(ymax[i]+ymin[i])/2-3); //ðàçìåòêà äëÿ òðàåêòîðèè for (int j=-4;j<5;j++) { pDC->MoveTo((xmax[i]+xmin[i])/2+(morphX/2)*j,(ymax[i]+ymin[i])/2-2); pDC->LineTo((xmax[i]+xmin[i])/2+(morphX/2)*j,(ymax[i]+ymin[i])/2+3); str.Format("%.1f",j*0.5); pDC->TextOut((xmax[i]+xmin[i])/2+(morphX/2)*j-5,(ymax[i]+ymin[i])/2+10,str); } for (j=-4;j<5;j++) { pDC->MoveTo((xmax[i]+xmin[i])/2-2, (ymax[i]+ymin[i])/2+(morphY/2)*j); pDC->LineTo((xmax[i]+xmin[i])/2+3, (ymax[i]+ymin[i])/2+(morphY/2)*j); str.Format("%.1f",-j*0.5); pDC->TextOut((xmax[i]+xmin[i])/2+10,(ymax[i]+ymin[i])/2+(morphY/2)*j-5, str); } for (i=1;i>=0;i--) { //îñè äëÿ îñòàëüíûõ ãðàôèêîâ pDC->MoveTo(xmin[i],ymin[i]); pDC->LineTo(xmin[i]+3,ymin[i]+10); pDC->MoveTo(xmin[i],ymin[i]); pDC->LineTo(xmin[i]-3,ymin[i]+10); pDC->MoveTo(xmin[i],ymin[i]); pDC->LineTo(xmin[i],ymax[i]); pDC->LineTo(xmax[i],ymax[i]); pDC->LineTo(xmax[i]-10,ymax[i]+3); pDC->MoveTo(xmax[i],ymax[i]); pDC->LineTo(xmax[i]-10,ymax[i]-3); //ðàçìåòêà äëÿ îñòàëüíûõ ãðàôèêîâ for (int j=0;j<10;j++) { pDC->MoveTo(xmin[i]+(morphX/2)*j,ymax[i]-2); pDC->LineTo(xmin[i]+(morphX/2)*j,ymax[i]+3); str.Format("%.1f",j*0.5); pDC->TextOut(xmin[i]+(morphX/2)*j-5,ymax[i]-20,str); } for (j=0;j<10;j++) { pDC->MoveTo(xmin[i]-2,ymax[i]+(morphY/2)*j); pDC->LineTo(xmin[i]+3,ymax[i]+(morphY/2)*j); str.Format("%.1f",-j*0.5); pDC->TextOut(xmin[i]+10,ymax[i]+(morphY/2)*j-5, str); } } //íàçâàíèÿ if (pOldFont != NULL) pDC->SelectObject(pOldFont);
i=2; strName="Òðàåêòîðèÿ ïîèñêà"; NameSize=pDC->GetTextExtent(strName); pDC->TextOut((xmax[i]+xmin[i]-NameSize.cx)/2,ymin[i]+30,strName); pDC->TextOut((xmax[i]+xmin[i])/2+10,ymin[i],"X2"); pDC->TextOut(xmax[i]-15,(ymax[i]+ymin[i])/2-25, "X1"); for (i=1; i>=0; i--) { if (i==0) strName="Ãðàôèê çíà÷åíèÿ ôóíêöèè ïî øàãàì"; if (i==1) strName="Ãðàôèê ðàññòîÿíèÿ îò òåêóùåé òî÷êè äî òî÷êè îïòèìóìà"; NameSize=pDC->GetTextExtent(strName); pDC->TextOut((xmax[i]+xmin[i]-NameSize.cx)/2,ymin[i]+30,strName); pDC->TextOut(xmin[i]+10,ymin[i],"X2"); pDC->TextOut(xmax[i]-15,ymax[i]-25, "X1"); } ////////////////////////////// // ñîáñòâåííî ãðàôèêè CPen pengreen(PS_SOLID, 5, RGB(0,255,0)); CPen penred(PS_SOLID, 5, RGB(255,0,0));
pDC->SelectObject(penred); pDC->MoveTo(morphX+(xmax[2]+xmin[2])/2, morphY+(ymax[2]+ymin[2])/2); pDC->LineTo(morphX+(xmax[2]+xmin[2])/2, morphY+(ymax[2]+ymin[2])/2);
pDC->SelectObject(pengreen); pDC->MoveTo(pDoc->XInst[0]*morphX+(xmax[2]+xmin[2])/2, pDoc->XInst[1]*morphY+(ymax[2]+ymin[2])/2); pDC->LineTo(pDoc->XInst[0]*morphX+(xmax[2]+xmin[2])/2, pDoc->XInst[1]*morphY+(ymax[2]+ymin[2])/2);
size.cx= xmax[0]+30; size.cy= ymax[0]+10; } else { pDC->TextOut(0, 0, "Ôóíêöèÿ (x2 - x1^2 )^2 + (1 - x1 )^2"); str="Íà÷àëüíàÿ òî÷êà ("+pDoc->Coord+')'; pDC->TextOut(0, Metric.tmHeight, str); pDC->TextOut(0, 2*Metric.tmHeight, "Òåîðåòè÷åñêàÿ òî÷êà îïòèìóìà (1;1)");
CString tmp; for (int k=0; k<pDoc->Iter; k++) { str.Format("%d",k+1); str="Ñèìïëåêñ "+str; pDC->TextOut(0,(4+6*k)*Metric.tmHeight, str); for (int i=0;i<3;i++) { tmp.Format("%d",i); str=" òî÷êå "+tmp+" ("; for (int j=0;j<2;j++) { tmp.Format("%.3f",pDoc->X[k][i][j]); str+=tmp+';'; } tmp.Format("%.3f",pDoc->Fx[k][i]); str=str.Left(str.GetLength()-1); str+=") ôóíêöèÿ ðàâíà "+tmp; pDC->TextOut(0,(5+i+6*k)*Metric.tmHeight, str); } tmp.Format("%d",pDoc->MaxF[k]); str="Ìàêñèìàëüíîå çíà÷åíèå ôóíêöèè íàáëþäàëîñü â òî÷êå "+tmp; pDC->TextOut(0,(8+6*k)*Metric.tmHeight, str); } size.cx= 500; size.cy= (4+6*pDoc->Iter)*Metric.tmHeight; } SetScrollSizes(MM_TEXT,size); }
void CSimplexView::OnInitialUpdate() { CScrollView::OnInitialUpdate();
CSize sizeTotal; // TODO: calculate the total size of this view sizeTotal.cx = sizeTotal.cy = 100; SetScrollSizes(MM_TEXT, sizeTotal); }
///////////////////////////////////////////////////////////////////////////// // CSimplexView printing
BOOL CSimplexView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); }
void CSimplexView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing }
void CSimplexView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing }
///////////////////////////////////////////////////////////////////////////// // CSimplexView diagnostics
#ifdef _DEBUG void CSimplexView::AssertValid() const { CScrollView::AssertValid(); }
void CSimplexView::Dump(CDumpContext& dc) const { CScrollView::Dump(dc); }
CSimplexDoc* CSimplexView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSimplexDoc))); return (CSimplexDoc*)m_pDocument; } #endif //_DEBUG
///////////////////////////////////////////////////////////////////////////// // CSimplexView message handlers
void CSimplexView::OnViewGraph() { // TODO: Add your command handler code here if (ViewCheck==0) { Invalidate (); ViewCheck=1; } }
void CSimplexView::OnViewTable() { // TODO: Add your command handler code here if (ViewCheck==1) { Invalidate (); ViewCheck=0; } }
int CSimplexView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CScrollView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here m_pDC = new CClientDC(this); // ïîëó÷åíèå óêàçàòåëÿ íà êîíòåêñò îêíà return 0; }
void CSimplexView::OnDestroy() { // TODO: Add your message handler code here m_bWorking=false; // Sleep(m_nThreadCounter*20); // çàñíóòü íà 20 ìèëëèñåêóíä äëÿ êàæäîãî ïîòîêà // m_nThreadCounter=0; delete m_pDC; m_pDC = 0; CView::OnDestroy();
}
void CSimplexView::OnUpdateViewSearchprocess(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if (ViewCheck==0 || m_bWorking==true) pCmdUI->Enable(false); else pCmdUI->Enable(true);
}
void CSimplexView::OnViewSearchprocess() { // TODO: Add your command handler code here Invalidate (); AfxBeginThread(SearchThread, this, THREAD_PRIORITY_IDLE); // m_nThreadCounter++; }
|
PS. Visual C++ 6.0
|