News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

plot a sinusoidal wave

Started by daniel.ioan, April 10, 2014, 02:27:56 AM

Previous topic - Next topic

daniel.ioan

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!

jj2007

Below an example that uses ArrayPlot, a macro of the MasmBasic library.

---------------------------------------------------
include \masm32\MasmBasic\MasmBasic.inc      ; download

.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.

dedndave

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/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

dedndave

http://aranna.altervista.org/data/ch05d.html

i guess PolyBezier isn't so bad for a pure sine function



notice that each control point (above and below) is actually used twice

dedndave

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



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

GoneFishing

Wow, Dave
Did you already upgrade to Windows 7 ? ... or it's simply a picture you found on internet ?

dedndave

it's from the article in the link   :P

daniel.ioan


daniel.ioan

i need another advice ....i want to draw  lines to have a axes and grid  :biggrin:

jj2007

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. During installation, when you see the help file, click on "try 50+ snippets".

daniel.ioan


dedndave

to draw grid lines, you can use MoveToEx and LineTo
you can draw them before or after the sine wave for different effects

dedndave

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: