星星闪亮的算法?(200分)

  • 主题发起人 主题发起人 歪就歪
  • 开始时间 开始时间

歪就歪

Unregistered / Unconfirmed
GUEST, unregistred user!
在我的PROJECT里,图形(BMP文件)显示一段导线,一个红色的亮
点从导线的一端移动到另一端,在移动到末端时,想让那红点象星
星或火花一样闪烁一下。

不要用GIF,不要第三家COMPONENT,只希望能有类似算法的代码,
愿奉送200分,谢谢。
 
频繁调用*.bmp文件。对此本论坛有过讨论!
 
JAMS:可能我没有说清楚,我要的是一个算法,而不是调用一个或几个BMP文件
因为我的图上并不仅仅是那一跟导线。同时,有了算法,我可以显示出闪烁的
过程(希望是那种摄影中加了星光镜的闪烁)。

再举个例子,水面的波纹扩散在图形学上是有算法来实现的,对吧?总不能LOAD
几十个水纹扩散的BMP来产生那种效果吧?如果那样,我还不如用PHOTOSHOP做
个GIF来显示。

谢谢。
 
可考虑用DirectDraw,用GDI实现这种算法的话,速度会很慢。
 
DirectX也可以。
 
用directDraw或是别的什么并不重要,关键是一个算法.
我有一个好主意,有很多网页用javascript实现了这个东西,你可以看看源码.
 
不知大虾可否这样:(我用VC时是这么做的,但还没用过DELPHI的线程)
生成一个线程,线程的入口是指向一个结构的指针,这个结构包括
设备上下文的句柄,需要闪烁的位置坐标(数组或链),然后通过线程
来画闪烁效果。关于图形学编程,在北京有以下几本编程的书:
《图形编程大师》电子工业(我还没看完,例子是DOS下的)
《电脑游戏编程与技巧大全》学苑出版
《图形编程指南》机械工业(每次去书店必看并必不买的书,很贵)
以上两本是id的人写的,很酷,值得一看。
图书大厦这类书比较全,你可以去发掘一下(有新发现别忘了通知弟兄门:))
如果你只是用于演示什么,我劝你用Director来作,好学的很,且能编译成exe文件(win95/dos)。
如果用delphi,我也觉得bmp的方法容易且效果会更好,自己画并不象预想的
那么好,我原来只是想让它眨眨眼睛就已经很老土了,而且,自己画别说
真彩了,256色都不见得用的很纯熟。
至于算法,我记得开发KPT的人有个网站,那里有些此类滤镜的算法,你可以去
yahoo英文去搜一下。


 
r/g/b 各加 X / DELAY /然后 减 X 看看?:")
 
Sorry, no chinese input here, so:

Const
歪就歪 = y9y

To cAkk: thanks, I agree, the key is 算法

To Crane: thanks, create a thread is not a problem and not must be.
and C++ is not too much different with the code, could I have your
code and try it Delphi?

Thanks all, but any other sugestion?

 
to y9y:
不好意思,那个程序我大二时当作业给交了,老师至今未还!:(
不过我这里有个线程的例子,我当时是从这个例子受启发
编出来的。不知对你有没有帮助:
一个MDI的程序
typedef struct{
HWND hWnd;
BOOL *lpKillThread;
} THREAD_INFO;

在CVIEW中生成线程:
void CThreadDemo1View::OnDraw(CDC* pDC)
{

....
// Store the window handle and the Kill flag.
m_ThreadInfo.hWnd = m_hWnd;//m_hWnd即相当于canvas.handel
m_ThreadInfo.lpKillThread = &m_bKillThread;
// Start the thread.//用于控制线程终止
m_pThread =
AfxBeginThread(ThreadProc, (LPVOID) &m_ThreadInfo);

}
线程中通过句柄来在窗口中画图(用线拼成的花在开放的动画)
UINT ThreadProc( LPVOID lpParam )
{
// Get a THREAD_INFO pointer from the
// parameter that was passed in.
THREAD_INFO *lpThreadInfo =
(THREAD_INFO *) lpParam;

// The next six variables represent
// values used to draw the spirograph;
unsigned char Red, Green, Blue;
int nFixedRadius = 80;
int nMovingRadius = 10;
int nMovingOffset = 70;

// Begin colors based on the system time. This
// makes the color somewhat random.
Red = (unsigned char)
( GetTickCount() & 0x000000ff );
Green = (unsigned char)
( ( GetTickCount() & 0x00000ff0 ) >> 4 );
Blue = (unsigned char)
( ( GetTickCount() & 0x0000ff00 ) >> 8 );

while( *lpThreadInfo->lpKillThread == FALSE ){

// Get a DC for the window.
HDC hdc = ::GetDC( lpThreadInfo->hWnd );

// Get the client rect so we can
// calculate the center point.
RECT Rect;
::GetClientRect( lpThreadInfo->hWnd, &Rect );
int nMidx = Rect.right / 2;
int nMidy = Rect.bottom / 2;

// Clear the window.
::InvalidateRect( lpThreadInfo->hWnd, NULL, TRUE );
::UpdateWindow( lpThreadInfo->hWnd );

// Create a pen based on the color. Select it
// into the DC and remember the old pen so
// we can select it back in later.
HPEN hPen, hOldPen;
hPen =
::CreatePen( PS_SOLID, 1, RGB( Red, Green, Blue ) );
hOldPen = (HPEN) ::SelectObject( hdc, hPen );

// Iterate through a bunch of times and
// draw the spirograph.
int prevx, prevy, x = 0, y = 0;
for( int i=0; i<=500; i++ ){

// Remember x and y.
prevx = x;
prevy = y;

// Calculate the new x and y.
x = (int) ( ( nFixedRadius + nMovingRadius ) *
cos( (double) i ) -
( nMovingRadius + nMovingOffset ) *
cos((double)(( ( nFixedRadius + nMovingRadius ) /
nMovingRadius ) * i ) ) );
y = (int) ( ( nFixedRadius + nMovingRadius ) *
sin( (double) i ) -
( nMovingRadius + nMovingOffset ) *
sin((double)(( ( nFixedRadius + nMovingRadius ) /
nMovingRadius ) * i ) ) );

// Draw the line (or move to the first
// point if this is the first time through).
if( i > 0 )
::LineTo( hdc, x + nMidx, y + nMidy );
else
::MoveToEx( hdc, x + nMidx, y + nMidy, NULL );

}

// Increment the color variables so
// that the colors move around.
Red += 6;
Green += 5;
Blue += 4;

// Increase the fixed radius and
// limit it to a max of 150.
nFixedRadius++;
if( nFixedRadius > 170 )
nFixedRadius = 90;
// Increase the moving radius and
// limit it to a max of 120.
nMovingRadius++;
if( nMovingRadius > 40 )
nMovingRadius = 10;

// Increase the moving offset and
// limit it to a max of 90.
nMovingOffset++;
if( nMovingOffset > 100 )
nMovingOffset = 70;

// Select the old pen into the DC,
// delete the pen we created, and
// release the DC we got.
::SelectObject( hdc, hOldPen );
::DeleteObject( hPen );
::ReleaseDC( lpThreadInfo->hWnd, hdc );

// Sleep so we don't chew up too
// much CPU time.
Sleep(100 );
}
return( 0 );

}


 
To Crane: Hi, thanks a lot, I will try that code in Delphi
To CJ: thanks, very 受启发...

If someone have any other good idea, please feel free tell me.
Thanks all
 
谢谢大家
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部