Hi.
I have homework where I must plot a sinusoidal wave , for which I know the amplitude and frequency . I know how to calculate the values of a sine function, but I need your help, because I don't know how to draw (plot) it in masm.
Thank you, cheers!
Below an example that uses ArrayPlot (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1182), a macro of the MasmBasic library.
---------------------------------------------------
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
.data
wcx WNDCLASSEX <WNDCLASSEX, CS_HREDRAW or CS_VREDRAW or CS_OWNDC, WndProc, 0, 0, 1, 2, 3, COLOR_BTNFACE+1, 0, txClass, 4>
txClass db "MbGUI", 0
.code
WinMain proc uses ebx ; this is the application's entry point
LOCAL msg:MSG
mov ebx, offset wcx
wc equ [ebx.WNDCLASSEX] ; we use an equate for better readability
mov wc.hInstance, rv(GetModuleHandle, 0) ; rv ("return value") is a Masm32 macro
mov wc.hIcon, rv(LoadIcon, eax, IDI_APPLICATION) ; OPT_Icon Smiley ; see \Masm32\MasmBasic\icons
mov wc.hIconSm, eax ; the rv macro returns results in eax
mov wc.hCursor, rv(LoadCursor, NULL, IDC_ARROW) ; get a cursor
invoke RegisterClassEx, addr wc ; the window class needs to be registered
invoke CreateWindowEx, NULL, wc.lpszClassName, Chr$("Hello Sinus"), ; set window title here
WS_OVERLAPPEDWINDOW or WS_VISIBLE,
400, 320, 530, 280, ; window position: x, y, width, height
NULL, NULL, wc.hInstance, NULL
.While 1
invoke GetMessage, ADDR msg, NULL, 0, 0
.Break .if !eax
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.Endw
exit msg.wParam
WinMain endp
WndProc proc uses esi edi ebx hWnd, uMsg, wParam:WPARAM, lParam:LPARAM
SWITCH uMsg
CASE WM_CREATE ; this message serves to initialise your application
Dim Sinus() As REAL8 ; example: in the CREATE handler,
xor ecx, ecx ; we fill an array with sinus values
push 180
fild stack ; stack is an equate for DWORD PTR [esp]
push ecx
fldpi
fdivr ; ST(0) is now 0.0174533
fstp REAL4 PTR stack[4]
.Repeat
mov stack, ecx
fild stack
fmul REAL4 PTR stack[4]
fsin
fstp Sinus(ecx)
inc ecx
.Until ecx>500 ; a few hundred are enough
pop ecx
pop eax
CASE WM_PAINT ; in the PAINT handler, we plot it onto the client area
ArrayPlot hWnd, RgbCol(200, 255, 240) ; init with window (or control) handle and background colour
ArrayPlot Sinus(), RgbCol(255, 0, 0)
ArrayPlot exit, "Sinus" ; finish with a title
CASE WM_DESTROY ; quit after WM_CLOSE
invoke PostQuitMessage, NULL
ENDSW
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
WndProc endp
end WinMain
---------------------------------------------------
To do the same "by hand" will require knowledge of
- WM_PAINT handler
- using a DC
- selecting colours into a DC
... and much more. Here is a raw list of the APIs used in the procedure that creates the plot:
invoke CreatePen, PS_SOLID, eax, dotcol
invoke SelectObject, APs.apMemDC, eax
call MbArrSort ; invoke MbArrSort Arr, count, pStringTable, mode
invoke GetClientRect, APs.apCtrl, addr APs.apRect ; yMin & yMax are on FPU
invoke CreateSolidBrush, dotcol
invoke SelectObject, APs.apMemDC, eax
invoke DeleteObject, [esi]
invoke CreatePolyPolygonRgn, pAllXY, addr pVertexCounts, ctVertex, WINDING
invoke FillRgn, APs.apMemDC, eax, stack
invoke SelectObject, APs.apMemDC, oldBrush
invoke DeleteObject, eax
invoke SelectObject, APs.apMemDC, oldPen
invoke DeleteObject, eax ; release pen
call MoveToEx ; MoveToEx, dc, x, y, 0
call LineTo ; LineTo, dc, x, y
call Rectangle ; hDc, left, top, right, bottom
call Ellipse ; hDc, left, top, right, bottom
Another simple option is to use the console - see the locate macro in the \Masm32\help section.
if you can break it up into small enough pieces, you can use MoveToEx and LineTo to draw lines between plotted points
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145069%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/dd145069%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145029%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/dd145029%28v=vs.85%29.aspx)
on the left-hand side of those pages, you will also see some Polyxxx functions
for example, you can create an array of points, then use Polyline or PolylineTo
if you have large gaps between points, you can use PolyBezier to fill in with curved lines
a bit more complex to use
http://aranna.altervista.org/data/ch05d.html (http://aranna.altervista.org/data/ch05d.html)
i guess PolyBezier isn't so bad for a pure sine function
(http://www.w3.org/TR/SVG11/images/paths/quad01.svg)
notice that each control point (above and below) is actually used twice
here's one i like
about 2/3 down the page is a section on Lissajous curves (sine waves on steroids)
http://www.codeproject.com/Articles/76878/Spirograph-Shapes-WPF-Bezier-Shapes-from-Math-Form (http://www.codeproject.com/Articles/76878/Spirograph-Shapes-WPF-Bezier-Shapes-from-Math-Form)
(http://www.codeproject.com/KB/WPF/SpirographShapes/LissajousCurves.gif)
i can make those curves on an oscilloscope by using sine-wave signals and the X and Y inputs
if the frequency on both inputs is the same, and in the same phase, you get the circle
if they're out of phase (still same frequency), you get a slanted circle
if they're different frequencies, you get the others
Wow, Dave
Did you already upgrade to Windows 7 ? ... or it's simply a picture you found on internet ?
it's from the article in the link :P
Thanks for help
i need another advice ....i want to draw lines to have a axes and grid :biggrin:
Attached an example with gridlines. The relevant code is in the WM_PAINT handler.
I also added a "console only" example to the snippets of MasmBasic (http://masm32.com/board/index.php?topic=94.0). During installation, when you see the help file, click on "try 50+ snippets".
thanks!
to draw grid lines, you can use MoveToEx and LineTo
you can draw them before or after the sine wave for different effects
in this program, i used different pen patterns when calling CreatePen
the grid lines, cursor lines, and reference lines are all drawn using MoveToEx and LineTo
the plots are drawn using PolyBezier
and, the high-res image is drawn using magic :biggrin:
(http://dedndave.x10.mx/files/EMTscan.bmp)