simple 2d line rotation help

Started by
1 comment, last by NigTronix 16 years, 11 months ago
Hey, I'm trying to make something like the second hand on an analog wall clock. I want a solid line to rotate from the center of the screen, 360 degrees. Below is my attempt(SIMPLIFIED): (But it isn't working correctly)

/*************************************************************************************
	RADAR_ME - An almost pointless program that tries to emulate a real radar or sonar
	screen.

	This version is conceptional version, that draws the radar to Device Context(0), or 
	the current global screen(desktop).


	Author: NigTronIX
	
	Date concepted: May 23, 2007 @ 12:07AM

	Last Modified: May 23, 2007 @ 2:07AM

	TODO: Threading optimizations, Transparent window, lighting effects or something
	
			- Move all Function declarations in header file after coding window code

		  I don't know, but I think my line drawing functions need optimized also ;P

		Thanks to my math book for rotating line formula!

	Compiled using Microsoft Visual C++ 6.0 under Windows XP Home SP1
              
				



***************************************************************************************/

#include <windows.h>
#include <conio.h> //debugging
#include <math.h>
#include <stdlib.h>
#include <stdio.h> //debugging
#include <time.h>
/* Global Constants */

#define DCON 0 // Device context to use

#define DegToRad 0.017453293f

/* Prototypes ^^ */

int Draw_line(); // returns 0 on failure, USED LATER
int Get_Center_Of_Screen(int *x, int *y); // returns 0 on failure, USED LATER

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
	
	/* Get Center of Screen */

	int cx = GetSystemMetrics(SM_CXSCREEN);
    int cy = GetSystemMetrics(SM_CYSCREEN);
    int pos1= cx / 2;
    int pos2= cy / 2;
	HDC hwnd = GetDC(DCON);
	int T = 1;

	while(1)
	{
        
        for(; T <= 60; T++) {

			SetPixel(hwnd,(cos(T) * pos1) - (sin(T) * pos2), (sin(T) * pos1) + (cos(T) * pos2) ,RGB(255,0,0));
			Sleep(1);
		}

		T = 1; // reset

	}




	return 0;
}


UPDATE: I now have it operating ALMOST the way I want it: but I want it to show only one line not multiple lines

	/* Get Center of Screen */

	int cx = GetSystemMetrics(SM_CXSCREEN);
    int cy = GetSystemMetrics(SM_CYSCREEN);
    int pos1= cx / 2;
    int pos2= cy / 2;
	HDC hwnd = GetDC(DCON);

	// General forumula: X =  X_Origin + cos(angle) * radius
	// Radius is the line length
	// Y = Y_Origin + sin(angle) * radius

	SaveDC(hwnd);

	while(1)
	{
        
        for(int T = 1; T <= (10); T++) {

			MoveToEx(hwnd, pos1, pos2, NULL); // update current brush  to origin
			LineTo(hwnd,pos1 + cos(T) * 200, pos2 + sin(T) * 200);
			RestoreDC(hwnd,1);

			Sleep(5);
			SaveDC(hwnd);
		}


	}

I'm trying to use SaveDC() and RestoreDC() to erase the lines before the new line is redrawn o.o I want a single line moving smoothly 360 degrees It's not working :( correctly Any help will be appreicated thanks :D, also anybody know how to specify line color and width? thanks [Edited by - NigTronix on May 24, 2007 7:39:43 AM]
Advertisement
Your approach to drawing this clock looks a bit haphazard. I assume your infinite 'while' loop where you're drawing the clock hand is nested in a WM_PAINT message block, yeah? If so, you need to get away from that; when you enter that while loop, no other Windows messages will be processed, which will give you much heartache later on.

An ideal approach for your situation might involve implementing something like the SetTimer function, which is detailed very nicely in the MSDN article located here. There are probably more accurate ways of tracking the time, but this may suit your purposes just right.

If you do implement the above approach, the general idea would be to trigger a repaint message every second which updates the clock, and in your WM_PAINT message block you would place the paint methods that you have and just simply paint the clock (with no 'while' loop). You only need to paint once per second (or however frequently your clock updates), as the paint buffer will maintain what was painted last until something else gets painted atop what you already have. If you need more help with this, let me know.

Finally, to specify line color and width, you will need to implement pens. HPENs, actually. Here's a quick demonstration of how to use a pen, with an explanation just below:

// create the pen, during some initialization process somewhere;// the following will create a solid-stroke pen, width 5, colored redHPEN myPen = ::CreatePen(PS_SOLID, 5, RGB(255, 0, 0));// later, during your painting...// select new pen and store the old penHGDIOBJ oldPen = ::SelectObject(hdc, myPen);// here, you would draw some lines, with LineTo and MoveToEx...// restore the old pen::SelectObject(hdc, oldPen);oldPen = NULL;

The code that directly answers your question involves the CreatePen method. With it, you can set a pen's style, width, and color.

The bit about storing the old pen and then restoring it after you're done painting is more of a good coding habit to get into, rather than some necessity. By storing the old pen and restoring it afterwards, you're maintaining what the previous pen is, which may need to be used later on by some process. If you don't restore the default pen in Windows applications, for instance, some odd painting consequences can arise. Something to consider in your programming journeys.

Also, when posting large amounts of code, it's helpful to the readers if you enclose your code within source tags, like so: [ source ] _code_here_ [ /source ] (except without any spaces between the brackets).

[Edited by - Omega147 on May 24, 2007 4:24:35 PM]
Thank you so much :D I'll try to implement it after school today, and I put the code in '' tags didn't know they were [ source ] on this forum.

This topic is closed to new replies.

Advertisement