News:

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

Main Menu

Get point relative to RECT

Started by Ar0n, January 28, 2016, 12:15:39 PM

Previous topic - Next topic

Ar0n

Hi guys, how can I map a point (POINT) from a RECT to another RECT? same as MapWindowPoints except that only with RECTs.

jj2007

Something like this?
lea eax, rc1
lea edx, rc2
movups xmm0, oword ptr [eax]
; add code to change the 4 dwords in xmm0
movups oword ptr [edx], xmm0

Ar0n

I didn't get you JJ :P for example, I have a point 100,100 (X, Y) in a RECT of 200x200 and I want to map it in a RECT of 100x100, it will be 50,50 (X, Y).

jj2007

Then you need to multiply all 4 elements by 0.5, right?

fild src_rc.left
fmul FP4(0.5)
fistp dest_rc.left
etc

qWord

Quote from: Ar0n on January 28, 2016, 12:15:39 PM
Hi guys, how can I map a point (POINT) from a RECT to another RECT? same as MapWindowPoints except that only with RECTs.
maybe this one does it for you (SEE1):
map_rect_points proc n:DWORD, points: ptr POINT, from: ptr RECT, to:ptr RECT
LOCAL last:ptr POINT

    mov edx,to
    mov ecx,from

    mov eax,[edx].RECT.right
    sub eax,[edx].RECT.left
    cvtsi2ss xmm0,eax           ; to.width
    mov eax,[edx].RECT.bottom
    sub eax,[edx].RECT.top
    cvtsi2ss xmm1,eax           ; to.height
    mov eax,[ecx].RECT.right
    sub eax,[ecx].RECT.left
    cvtsi2ss xmm2,eax           ; from.width
    mov eax,[ecx].RECT.bottom
    sub eax,[ecx].RECT.top
    cvtsi2ss xmm3,eax           ; from.height

    divss xmm0,xmm2             ; factor for x-Coord. = to.width / from.width
    divss xmm1,xmm3             ; factor for y.Coord. = to.height / from.height

    mov edx,points              ; ptr to current POINT

    mov eax,n
    lea eax,[edx+eax*POINT]
    mov last,eax                ; ptr to end of points-array

    .while edx < last           ; for all POINTs in array

        cvtsi2ss xmm2,[edx].POINT.x
        cvtsi2ss xmm3,[edx].POINT.y
        mulss xmm2,xmm0               ; points[i].x *= to.width / from.width
        mulss xmm3,xmm1               ; points[i].y *= to.height / from.height
        cvtss2si eax,xmm2
        cvtss2si ecx,xmm3
        mov [edx].POINT.x,eax
        mov [edx].POINT.y,ecx

        add edx,POINT
    .endw

    ret
map_rect_points endp

MREAL macros - when you need floating point arithmetic while assembling!

dedndave

wow - you guys jump on FPU and SSE code to perform simple integer math ?   :icon_eek:

dedndave

we do need a little more info than is given - but integer math should do the trick

a RECT (200x200, as you mentioned) has left, top, right, and bottom coordinates
so, the 200x200 RECT might be 10,10,210,210

otherwise, you just have a box of 200x200 dimension

or are the left and top coordinates always 0 ?

qWord

Quote from: dedndave on January 28, 2016, 05:02:27 PM
wow - you guys jump on FPU and SSE code to perform simple integer math ?   :icon_eek:
N points => 2*N integer divisions?
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

one DIV for vertical
one DIV for horizontal (if scale is different than vertical)
then two MUL's for each point

HSE

For better precision I think you need first MUL an later DIV.
If there are more points it is more easy to calculate REAL factors only one time and later multiply that factors for every point.
Regards.
 
Equations in Assembly: SmplMath

jj2007

include \masm32\MasmBasic\MasmBasic.inc      ; download
.data
src       RECT <1000, 1100, 1200, 1300>
dest      RECT <?>
align 16
factor    REAL4 4 dup(0.2)

  Init
  movups xmm0, src
  mulps xmm0, oword ptr factor
  movups dest, xmm0
  deb 4, "Source rect", src.left, src.top, src.right, src.bottom
  deb 4, "Dest rect", dest.left, dest.top, dest.right, dest.bottom
EndOfCode


Output:
Source rect
src.left        1000
src.top         1100
src.right       1200
src.bottom      1300

Dest rect
dest.left       200
dest.top        220
dest.right      240
dest.bottom     260