News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

scaleshape isn't accurate enough?

Started by Alex, May 24, 2007, 03:32:52 AM

Previous topic - Next topic

Alex

i'm trying to scale my shape, but it keeps shrinking into the center when it should continuously expand and contract.
it expands and contracts, but every time it shrinks a tiny bit.
Is it just not accurate enough? Have any idea as to how I can make it expand contract continously?


Psub sscale(c1)
If shapes2(c1).scale <> 0
shapes2(c1).scale360 = WrapAngle(shapes2(c1).scale360,shapes2(c1).scale)

ScaleShape shapes2(c1).shape,1+SinRadius(shapes2(c1).scale360,shapes2(c1).scalem)
;RefreshShape shapes2(c1).shape
EndIf
EndPsub

kevin

#1
     With ScaleShape,  I wouldn't do it more than once,  the more frequently you do, the more error you'll introduce to the original geometry.    I think you want RotateShape here.

     ScaleShape works differently then RotateShape for example.  When we rotate the mesh, the original geometry is not changed.  Since this is assumed to the dynamic request (i.e drawing the result/collision etc).   With Scaling you permanently resizing the shape.  
   

i.e

PlayBASIC Code: [Select]
   s=newconvexshape(30,5)

Do
Cls 0


Scale#=5+Cos(zoomAngle#)*4
RotateShape s,0,Scale#

zoomAngle#=wrapangle(zoomAngle#,1)

drawshape s,400,300,2

Sync
loop


Draco9898

I get it, your talking about rounding errors...It looks like rotate shape like kevin suggested would work perfectly.
DualCore Intel Core 2 processor @ 2.3 ghz, Geforce 8600 GT (latest forceware drivers), 2 gigs of ram, WIN XP home edition sp2, FireFox 2.

"You'll no doubt be horrified to discover that PlayBasic is a Programming Language." -Kevin

Alex

thing is, I need the geometry changed.
If the geometry isn't changed, my collisions wont be right for the scaled shape I believe because it would be checking the original geometry and not the new ones. correct?

i'll try anyways..

Alex

#4
edit:

yeah, just checked and even though it resizes it, the geometry stays the same, so if I need to get the new position of any vertexes, It will only be able to get the original ones, and not the resized ones.

I need to get the new positions for my collisions to work.

Alex

ok, here's a workaround I came up with which works..


Psub sscale(c1)
If shapes2(c1).scale <> 0
shapes2(c1).scale360 = WrapAngle(shapes2(c1).scale360,shapes2(c1).scale)

For v1=0 To shapes2(c1).points-1
distance# = GetDistance2D(0,0,GetShapeVertexX(shapes2(c1).shape,v1),GetShapeVertexY(shapes2(c1).shape,v1))
angle# = GetAngle2D(0,0,GetShapeVertexX(shapes2(c1).shape,v1),GetShapeVertexY(shapes2(c1).shape,v1))
SetShapeVertex shapes2(c1).shape,v1,CosRadius(angle#,distance#+SinRadius(shapes2(c1).scale360,shapes2(c1).scalem)),SinRadius(angle#,distance#+SinRadius(shapes2(c1).scale360,shapes2(c1).scalem))
Next
RefreshShape shapes2(c1).shape


EndIf
EndPsub



Alex

#6
edit:
hm, actually it gets a bit morphed if the center of the shape is offset and point sarent all equal distance to center.. hmm

edit2:
ok, i got it to keep scale, but now it shrinks like before.. :(
so I guess that wont work.


Psub sscale(c1)
If shapes2(c1).scale <> 0
shapes2(c1).scale360 = WrapAngle(shapes2(c1).scale360,shapes2(c1).scale)

For v1=0 To shapes2(c1).points-1
distance# = GetDistance2D(0,0,GetShapeVertexX(shapes2(c1).shape,v1),GetShapeVertexY(shapes2(c1).shape,v1))
angle# = GetAngle2D(0,0,GetShapeVertexX(shapes2(c1).shape,v1),GetShapeVertexY(shapes2(c1).shape,v1))
SetShapeVertex shapes2(c1).shape,v1,CosRadius(angle#,distance#+SinRadius(shapes2(c1).scale360,shapes2(c1).scalem*distance#)),SinRadius(angle#,distance#+SinRadius(shapes2(c1).scale360,shapes2(c1).scalem*distance#))
Next
RefreshShape shapes2(c1).shape

EndIf
EndPsub

Alex

ok, figured out a real workaround I think..

it involves having to manually reset all the shapes at the end of each gameloop, which means you need a copy of each original shape at hand to revert back to.

with that functioning, I also have the calculation needed to produce a correct scaling/resizing of shapes:


Psub sscale(c1)
If shapes2(c1).scale <> 0
shapes2(c1).scale360 = WrapAngle(shapes2(c1).scale360,shapes2(c1).scale)

For v1=0 To shapes2(c1).points-1
distance# = GetDistance2D(0,0,GetShapeVertexX(shapes2(c1).shape,v1),GetShapeVertexY(shapes2(c1).shape,v1))
angle# = GetAngle2D(0,0,GetShapeVertexX(shapes2(c1).shape,v1),GetShapeVertexY(shapes2(c1).shape,v1))
SetShapeVertex shapes2(c1).shape,v1,CosRadius(angle#,(distance#+CosRadius(shapes2(c1).scale360,-shapes2(c1).scalem*distance#))-(-shapes2(c1).scalem*distance#)),SinRadius(angle#,(distance#+CosRadius(shapes2(c1).scale360,-shapes2(c1).scalem*distance#))-(-shapes2(c1).scalem*distance#))
Next

RefreshShape shapes2(c1).shape

EndIf
EndPsub

Draco9898

#8
Your SetShapeVertex is about the longest command string I've ever seen, that's nuts.

Yes, I had a similar idea about your problem earlier, I was thinking you could keep a back-up copy of a shape so you can switch them back when you needed. I didn't post it because I believed rotate would have fixed it.

Nice.
DualCore Intel Core 2 processor @ 2.3 ghz, Geforce 8600 GT (latest forceware drivers), 2 gigs of ram, WIN XP home edition sp2, FireFox 2.

"You'll no doubt be horrified to discover that PlayBasic is a Programming Language." -Kevin

kevin


  You can of course do collision intersections after calling RotateShape.  ie.




s=newconvexshape(30,5)

x1=100
y1=100

Do
Cls 0

Scale#=5+Cos(zoomAngle#)*4
RotateShape s,0,Scale#


if mousebutton()=1
x1=mouseX()
y1=mouseY()
endif

x2=mouseX()
y2=mouseY()

; Detect intersection, calc first and second ponit
result=linehitshape(x1,y1,x2,y2,s,400,300,1)


DrawShape s,400,300,2
linec x1,y1,x2,y2,rgb(255,0,0)

if result
circlec getintersectx#(0),getintersecty#(0),5,true,rgb(255,255,0)
endif

zoomAngle#=wrapangle(zoomAngle#,1)

Sync
loop