For other topics related to the FreeBASIC project or its community.
dodicat
Posts: 6552
Joined: Jan 10, 2006 20:30
Location: Scotland

The rectangle centre starts at the screen centre, it's direction is towards the bottom left corner.
that is along the line (xres/2,yres/2) to (0,yres)

The gradient of it's line of motion is (dy by dx), i.e. (yres/2-yres)/(0-xres/2)
The normal to a line of gradient dy/dx is -dy/dx.
That is in 2D co-ordinate geometry, normal= -1/gradient.

The length of the side is 2* .5*SmallRectangleHeight*normalize(normal)
Because the normalize(normal) has a length of one unit.

Here's a slight improvement, by making sure that the bottom point is lifted into the screen fully by a do until loop.

Code: Select all

`'beeper'extern "windows" lib "user32"declare function _Beep alias "MessageBeep" (byval as integer) as integer'end externType V2D    As Single x,yEnd Type#define vct Type<V2D>Function Rotate2D(pivot As V2d,p As V2d,a As Single) As V2D    var rotx=(Cos(a*.0174533)*(p.x-pivot.x)-Sin(a*.0174533)*(p.y-pivot.y))+pivot.x    var roty=(Sin(a*.0174533)*(p.x-pivot.x)+Cos(a*.0174533)*(p.y-pivot.y))+pivot.y    Return vct(rotx,roty)End FunctionOperator + (v1 As V2D,v2 As V2D) As V2DReturn vct(v1.x+v2.x,v1.y+v2.y)End OperatorOperator -(v1 As V2D,v2 As V2D) As V2DReturn vct(v1.x-v2.x,v1.y-v2.y)End OperatorOperator * (f As Single,v1 As V2D) As V2D 'scalar*V2DReturn vct(f*v1.x,f*v1.y)End OperatorFunction length(v As V2D) As Single    Return Sqr(v.x*v.x+v.y*v.y)End FunctionFunction normalize(v As V2D) As V2D    Dim n As Single=length(v)    If n=0 Then n=1e-20    Return vct(v.x/n,v.y/n)End FunctionDim As Integer xres,yres'===================================================='INPUTSDim As Single SmallRectangleHeight=300Dim As Single BigRectangleWidth=800Dim As Single BigRectangleHeight=600Dim As Single rotateangle=.01  'degrees(tweakable)'=================================================If BigRectangleHeight>BigRectangleWidth Then Swap BigRectangleHeight,BigRectangleWidthScreenres BigRectangleWidth,BigRectangleHeightScreeninfo xres,yresDim As V2D ctr=vct(xres/2,yres/2)'screen centre and centres of rectanglesDim As Single ds,diffx,diffy,incDim As V2D start,norm,temp,temp2,temp3Dim As Integer flagstart=vct(0,yres)-ctr#macro motion(inc)clsds=ds+inc 'motion increments'(dy/dx)= a gradient, -(dx/dy)= a normal to a gradient'i/e.  swap start.x,start.y for (dx/dy), then negate.    norm=vct(-start.y,start.x) 'get the normal vector to the direction of travel    norm=.5*SmallRectangleHeight*normalize(norm)'make the normal vector size= .5*SmallRectangleHeight    temp=ctr+ds*start  'move the SmallRectangle centre onwards    temp2=temp+norm  'top point-red dot    temp3=temp-norm  'bottom point-red dot    Line(temp3.x,temp3.y)-(temp2.x,temp2.y)'join top to bottom points    Circle(temp2.x,temp2.y),3,4,,,,f       'then circle them for the dots    Circle(temp3.x,temp3.y),3,4,,,,f#endmacroDo    Screenlock        motion(.001)        'Finishing condition    If temp2.x<=0 Then 'if top point is on the big rectangle(side) i.e done        diffy=yres-temp2.y:diffx= temp3.x         'finish off the other rectangle sides        Line(xres-diffx,0)-(xres,diffy)        Line(temp3.x,yres)-(xres,diffy)        Line(xres-diffx,0)-(temp2.x,temp2.y)        Screenunlock:_Beep(-1):Exit Do    End If        If temp3.y>=yres Then 'if bottom point is on the big rectangle (base)        If temp2.x>0 Then 'if top point is still in the big rectangle (screen)            do            start=rotate2D(ctr,start,rotateangle)'lift the bottom point up into the screen            'no forwaed motion while lifting            motion(0)            loop until temp3.y<yres                                                        End If    End If    Screenunlock    Sleep 1,1    If Len(Inkey) Then flag=1: Exit DoLoop If flag=0 Then    Print "Length of inside rectangle = ";length(vct(temp3.x,yres)-vct(xres,diffy))    Print "Height of inside rectangle = ";length(temp2-temp3)Else    Print "Exit"End IfSleep `
owen
Posts: 554
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

At dodicat _ thanx
note: i am unable to view all your code on my cell phone. I'm a truck driver and will be able to view everything on my laptop in a few days.
the gradient or direction is negative due to decrease in x. it's a ratio is that of the large rectangles height to width. The norm however should be the perpendicular of the chord. Which is what mystifies me as to how you get it spot on correct.
owen
Posts: 554
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

`Dim As Double piDim As Double radDim As Double x,yDim As Double r1h,r1w,r1x1,r1y1,r1x2,r1y2,r1x3,r1y3,r1x4,r1y4,r1cx,r1cyDim As Double r2h,r2w,r2x1,r2y1,r2x2,r2y2,r2x3,r2y3,r2x4,r2y4Dim As Double angle,difangleDim As Double bapi = 4 * Atn(1)rad=pi/180r1h=400r1w=600r1x1=0r1y1=r1hr1x2=r1wr1y2=r1hr1x3=r1wr1y3=0r1x4=0r1y4=0r1cx=r1w/2r1cy=r1h/2r2h=250r2x2=r1x2r2y2=r1hangle=atan2((r2h/2),Sqr((r1h/2)^2 + (r1w/2)^2 - (r2h/2)^2)) / raddifangle=atan2((r1h/2),(r1w/2))/rad - angleangle=360-angle+difanglex=r1cx+cos(angle*rad)*sqr((r1h/2)^2 + (r1w/2)^2)Do While x-r1x2 > .0001   r2x2=r2x2-(x-r1x2)   angle=atan2((r2h/2),Sqr((r1h/2)^2 + (r2x2-r1cx)^2 - (r2h/2)^2)) / rad   difangle=atan2((r1h/2),(r2x2-r1cx))/rad - angle   angle=360-angle+difangle   x=r1cx+cos(angle*rad)*sqr((r1h/2)^2 + (r2x2-r1cx)^2)loopy=r1cy+sin(angle*rad)*sqr((r1h/2)^2 + (r2x2-r1cx)^2)r2x1=0r2y1=r1h-yr2x3=r1wr2y3=yr2x4=r1w-r2x2r2y4=0r2w=Sqr((r2x2-r2x1)^2 + (r2y2-r2y1)^2)Print r2wLine(r1x1,r1y1)-(r1x2,r1y2)Line(r1x2,r1y2)-(r1x3,r1y3)Line(r1x3,r1y3)-(r1x4,r1y4)Line(r1x4,r1y4)-(r1x1,r1y1)Line(r2x1,r2y1)-(r2x2,r2y2)Line(r2x2,r2y2)-(r2x3,r2y3)Line(r2x3,r2y3)-(r2x4,r2y4)Line(r2x4,r2y4)-(r2x1,r2y1)`