-
Nov 20th, 2000, 08:13 AM
#1
Thread Starter
New Member
Hi! Does anyone know how I can treat a circle that is drawn in VB as an object?
I want to avoid both circles from colliding into each other.
How do I code that?
Thank you!
-
Nov 20th, 2000, 08:27 AM
#2
Addicted Member
Shape
You could use the Shape control.
Shrog
-
Nov 20th, 2000, 10:28 AM
#3
transcendental analytic
Do you have code for moving the shapes, as you say you want to detect collisions?
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Nov 20th, 2000, 12:51 PM
#4
Addicted Member
A movin' and a groovin'
OK, the first thing to remember here is that the shape control can be wider than it is high (or vice versa) even if it contains a circle or square. So make sure that the width and height of the control is the same. Unless of course you're working with elipses or rectangles, but you did say you wanted circles.
Now we know exactly where the top left corner of each shape control is. All we have to do is measure the distance between these two points. If the distance is less or equal to the radius of circle1 plus the radius of circel2, we have collision.
What is the radius of the circles? Half the width of the control.
Code:
Dim Radius1 As Single
Dim Radius2 As Single
Dim CollisionDistance As Single
Radius1 = shpCircle1.Width / 2
Radius2 = shpCircle2.Width / 2
CollisionDistance = Radius1 + Radius2
There are three ways of checking to see if the distance is within range: the Fast way, the Accurate way and the special Shrog way (for lack of a better name).
Code:
Dim DistX As Single
Dim DistY As Single
Dim Distance As Single
DistX = Abs(shpCircle1.Left - shpCircle2.Left)
DistY = Abs(shpCircle1.Top - shpCircle2.Top)
'The Fast Method
If DistX <= CollisionDistance Then
If DistY <= CollisionDistance Then
'We have collision
End If
End If
'The Accurate Method
Distance = Sqr(DistX * DistX + DistY * DistY)
If Distance <= CollisionDistance Then
'We have collision
End If
'The Shrog method
If DistX <= CollisionDistance Then
If DistY <= CollisionDistance Then
Distance = (DistX + DistY) * .707
If Distance <= CollisionDistance Then
'We have collision
End If
EndIf
End If
The last method is much more accurate than the Fast method, but much faster than the accurate method.
If you wonder where the .707 comes from, it is half Sqr(2) or the sine of 45 degrees (also the cosine of 45). Don't know if this will mean anything to you.
Anyway, you will have to decide which method to use, depending on your particular needs.
Hope this helps.
Shrog
-
Nov 20th, 2000, 02:18 PM
#5
transcendental analytic
Might be a bit late but yeah, that's how it generally works, the detection can actually be simplified to
Code:
Collision = Radius1 + Radius2 > ((X1-X2)^2+(Y1-Y2)^2)^0.5
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Nov 21st, 2000, 01:34 AM
#6
Addicted Member
Too slow
Your simplified version is a nice place to start, but it's not very effective.
The chances are very good that this calculation will be done on several objects, and not just two. The chances are also that this should happen many times per second. A hundred little steps per second gives a much better effect than four or five jumpy movements per second, so speed is of the utmost importance.
To slow your version down, you calculate Radius1 + Radius2 each and every time. If the radii (I think that's the plural) never change, you only need to do that once, as in my "CollisionDistance" variable.
To slow it down even more, you use (...) ^ 0.5
Sqr(...) is much faster.
Also, X * X is very much faster than X ^ 2
By nesting the if statements:
Code:
If DistX <= CollisionDistance Then
If DistY <= CollisionDistance Then
before calculating the distance, you can more than double the speed of the opperation. With your one-line version, this is not possible.
Once you've discovered whether there is a collision or not, what do you do with this information? Do you "bounce" the objects off each other? Take evasive action? Whatever you do, you would most like want to use DistX and DistY, which in your example you would have to recalculate as X1-X2, because you did not store it the first time you calculated it.
To fit everything into one line, you have to use variable names like X1 an Y2. Just because it's one line, don't mean it's more readable.
You offer only one way - accurate and slow. I often need to sacrifice a little accuracy for speed, or speed for accuracy, hence my three different ways.
Lastly, instead of saying "If A > B Then", you say "Collision = A > B". This does not really simplify things, because you will probably still have to use it in an if statement somewhere, as in "If Collision Then".
I am sorry that I totally ragged your version, but I could not resist using it to demonstrate the difference between a showroom way and practical way of doing things.
Shrog
-
Nov 21st, 2000, 02:10 AM
#7
transcendental analytic
I'm amazed there's someone who can speak so much about effectivity, i'm usually always against anything else but effectivity, except for compressed code, a bit stupid of me. It actually kills me thinking about how much speed i could save not doing what i sometimes do. So sorry for being so ignorant. But sometimes i'm so tired i don't care and here i'm talking to a guy who wants to detects collision with a couple of shapes, why would i care to speak of the nanoseconds he could gain whereas you loose tons on handling the controls themselves?
Thanks for noticing me about ^0.5, i've been using sqr until someone told me ^0.5 is faster, without even doing tests
As for me using Collision variable i'm just pointing out the outcome is a boolean, you use it how you want to use it, and if statements require this you don't need to store the variable in between.
It's really obvious i was wrong and you were right but i'm sure were just fussing over nothing, this would be more relevant if we were talking about any speed critical algoritms used in games, btw you suggested the shape control yourself, well hope you don't mind but we should just ask mybren of his opinion?
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Nov 21st, 2000, 03:00 AM
#8
Addicted Member
Yeah, I actually feel bad about being so harsh on your code.
When I suggested the shape control, it was actually a cop-out answer; I didn't really mean it. It's just the first thing that comes to mind when one thinks of a circle object.
Mybren is not online at the moment, but I'll wait. Pitty about my 7 hour time difference - I'm only online during the quiet hours.
Shrog
-
Nov 22nd, 2000, 07:50 AM
#9
Thread Starter
New Member
Circles, circles, circles
Hello there! Firstly, thank you so much for both your opnions & help.
Actually, I'm creating a learning tool. And the circles are to represent nodes in the topology. The problem I am facing is how to avoid the nodes from overlapping each other and lines from overlapping the nodes as well.
The nodes and lines are supposed to be user drawn. So I'm trying to make sure the lines will stop once it reaches the node/circle. And that the user will not place another noce/circle too near a previously drawn node/circle.
I had problems using the Shape tool because I couldn't reinstantiate the circle.
I tried using :
=====================================
Dim circle() as Shape
Set circle(counter) = New shpCircle
=====================================
This caused errors, is there anyway I can do it besides this?
And I don't know how to pass the X and Y co-ordinates so that the circles can be placed at the position where the user has clicked the mouse on.
Is there a way I can pass parameters to a shape object?
Thank you in advance for any help you can offer.
-mybren-
-
Nov 22nd, 2000, 08:10 AM
#10
Addicted Member
Shape Control
The Shape control is a control, like a command button and can be found on your toolbox. You create it on your form the same way you would a command button or any other control. It has a Left and Top property like other controls, and you can use these to position the control. You also have a Line control.
The way you want to use this is not exactly what I had imagined, but the coding that we posted before will tell you whether the circles are overlapping or not.
Shrog
-
Nov 22nd, 2000, 08:12 AM
#11
transcendental analytic
To create new shapes in an array of shapes you use Controls.Add method of the form:
Code:
Private Shapes() As Shape
Private Sub Form_Load()
ReDim Shapes(9)
For x = 0 To 9
Set Shapes(x) = Controls.Add("VB.Shape", "ShapeX" & x)
With Shapes(x)
.Visible = True
.Move x * 100, x * 100, 200, 200
.Shape = 2
End With
Next x
End Sub
The shape property of shape object can be set to circle(2)
To place a circle on the coordinates at mouse X and Y you use the X and Y parameters at the mouseDown event of the form. And move is the method to use.
How are the lines going to be drawn? Do you need ability to move them after having them set? What do you mean by "stop once it reaches a circle" ? Are the lines connected to the nodes?
Use
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Nov 22nd, 2000, 10:49 AM
#12
Thread Starter
New Member
I'm amazed!
wow, I'm really grateful, you guys have been the best at answering my questions. I'm very much a newbie, and all the help you've given has really helped.
What i meant by "stop once it reaches a circle" is that the user will draw the lines. And once the user releases the mouse on top or around the node area, then the line will be linked to that particular node. This has been a major headache!
I'll try fixing my code again and keep you guys updated on my progress. Thanks a lot!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|