5 Replies Latest reply on Mar 6, 2015 7:52 AM by Rod@FOF

# Help with sprite constrained movement along edge of an irregular bitmap or vector shape.

Hello,

I need to be able to constrain the movement of a "wheel" along the edge of an irregular bitmap or vector shape. In addition, as the "wheel" moves along the path, it needs to return the cumulative length of the traveled path in pixels.

What this is for is to demonstrate the measurement of something called "sight distance." The process involves moving two sighting rods apart until the lower portion of one is no longer visible from the other, then running an odometer wheel along the irregular road path to measure the actual travel distance between the two rods.

I have been able to complete the first part of this, with two rods connected by a "sight line" being moved apart over an irregular vector shape until the sight line becomes invisible. And this returns the distance these two rods are separated by, in feet, by using 1 pixel = 1 foot. A segment of that movie appears below. The wheel would need to run over grey slopes after red sight line disappears as it is moved behind the hill.

Of course, moving the wheel over the edge of the irregular shape and returning the actual distance of the path in pixels is the hard part of this. I seem to recall James Newton and others had developed several methods for constraining the movement of a sprite along the edge of another shape. But I have been unable to find these behaviors. In addition, I know calculating the distance traveled by the wheel is going to be somewhat complicated as I suspect it will require calculating the hypotenuse of several rise and run triangles, with new triangles being added when the direction of the irregular surface changes.

Can anyone offer some help at least with getting the constrained movement of a sprite("wheel") along the edge of the bitmap or vector shape?

Rod Wolford

• ###### 1. Re: Help with sprite constrained movement along edge of an irregular bitmap or vector shape.

Hi Rod,

Perhaps you're looking for this:

http://nonlinear.openspark.com/tips/dragging/irregular/

In addition, I know calculating the distance traveled by the wheel is going to be somewhat complicated as I suspect it will require calculating the hypotenuse of several rise and run triangles, with new triangles being added when the direction of the irregular surface changes.

How irregular is your shape going to be? If it is just a series of triangles, then it should be simple. If you know in advance what the triangles are going to be, then it is even simpler.

Perhaps you can find some inspiration here:

Can you give examples of how the irregular surface is to be created?

Cheers,

James

• ###### 2. Re: Help with sprite constrained movement along edge of an irregular bitmap or vector shape.

Wow! Thanks for the quick reply. I will check out the resources you have provided.

In the meantime concerning the irregular surfaces to be created, one option would be to have a vector shape with about eight adjustable vertices that the user can drag to create typical roadway type layouts.

In general, most examples will be similar to the shape I provided in my post with a couple of ups and downs with slopes no more severe than those shown. Of course, in the ideal world these would be curved shapes rather than triangular, but as a simulation it is not completely necessary to do that.

Another option would be for these to be bitmapped shapes that could be loaded from a folder. If this was done, then a specified size for the bitmap would be given, perhaps 200 X 800 and trainees could load actual road layouts from engineering drawings that corresponded to the scale requirements (as it happens 800 feet with slopes of about 6 to 10 degrees accounts for most vertical sight distance measurements. Here, though, shapes would not be triangles.

I really appreciate you taking the time to answer this. It is a problem I really need to solve and time is always the problem.

After I review your materials, I will respond back. Your work has always been the best.

Regards,

Rod

• ###### 3. Re: Help with sprite constrained movement along edge of an irregular bitmap or vector shape.

Hi James,

I tried to open your movie, but it is in a newer version than I am using. I am still using MX2004. I do have 11.5 on another machine, but if possible, can you save it more MX2004?

Thank you,

Rod Wolford

• ###### 4. Re: Help with sprite constrained movement along edge of an irregular bitmap or vector shape.

Hello James,

I want to thank you very much for the vertex solution for calculating an irregular line length you provided to me in your sample movie. I have been playing with it over the past few days. It is perfect and I have used it to accomplish several things.

First, I am storing values for each line segment length in a list and I am working on a process to sum those segments of the line to return the distance intersected by the pair of sighting rods dragged along the irregular path. The approach I am taking has two steps. 1) Look at the locH of each sighting rod and sum all the line segments fully contained between those two points. 2) Then for line segments partially contained within the locH of the sighting rods I am trying to find a solution to determine that length. I think that I should just be able to make a ratio from the distance of the locH of a sighting rod to the horizontal point of a vertex of a line segment within its bounds to the horizontal point of the horizontal point of the other vertex of that line which is outside the area bound by the sighting rods. Multiply the line segment length by the ratio and it should be a fair approximation of that length of the line segment. I am sure a more accurate method would be to calculate those partially contained segments based on the segment's length and slope, but I may be to lazy to work through that, though I think your movie code contains the seeds of that solution.

Second, I am working on controls that allow a user to grab and move each of the vertices to form new irregular shapes. At this point, I have created eight input fields that allow the vertical location of each vertex point to be varied (while holding the horizontal point constant). Next step, I hope, will be mouseover points at each of the vertices enabling them to simply be dragged on mousedown to new locations.

The first link to the irregular constraint was, in fact, the movie I had seen several years ago. So far as I can tell, it won't work for what I am trying to do. First it seems to work only with bitmaps. Second, I am not sure how I would be able to alter the shape as I need to do. The vertex solution is much better. And finally I haven't figured out how to make it track the outside of the shape rather than the inside (though I imagine I could figure it out if not for the fact that your vertex solution seems like it will let me do what I want to do). So I am still going to be working on finding a way to make the sighting rods track the irregular line. But in the scheme of things, it is a lesser problem.

Anyway, big thanks for the movie script you provided. I wanted you to know that the time you took to provide the help was not wasted.

Regards,

Rod

• ###### 5. Re: Help with sprite constrained movement along edge of an irregular bitmap or vector shape.

Just thought I would share the behavior I developed for calculating the sight distance path based on help from James Newton. Unfortunately, it isn't a "wheel" that is pushed along the path to return the path length. Instead, point 1 is clicked on the path, then point 2. This causes a line segment along the path to be drawn and its length to be stored in a field. The process is repeated until the path between the two sight rods is outlined. Not ideal, but what I could accomplish. Maybe a better solution exists?

property spritenum

global gLoc1, gLoc2, myimage, gVlist, vDistance

On beginsprite

gloc1=0

gloc2=0

member("instructions").text = "" -- a field to contain instructions for how to use the tool

member("distancesum").text = "" -- a field to contain the summed distances along the path

member("Sight Distance").text = "" -- a field to contain the sight distance, line of sight, measured by the sighting rods

gVlist =[]  -- a list to store the line segment values not used in this behavior, but used elsewhere

end

on mousewithin

sprite(spritenum).cursor = 271 --3

If gLoc1  = 0 and gLoc2 = 0 then member("instructions").text = "click point 1"

If gLoc1 <> 0 and gLoc2 = 0 then member("instructions").text = "click point 2"

If gLoc1 <> 0 and gloc2 <> 0 then member("instructions").text = ""

end

on mouseleave

member("instructions").text = ""

end

on mousedown

myImage = window("stage").image --creates the stage image to draw on

if member("DistanceSum").text = "" then member("DistanceSum").text = string(0)

if gLoc1 = 0 then

gloc1 = the mouseloc -- records the first location along the path

else

gloc2 = the mouseloc -- records the second location along the path

end if

if gloc1> 0 and gloc2 > 0 then

distanceBetween(gloc1,gloc2)

vDistance =vDistance

end if

end

on DistanceBetween(aPoint1, aPoint2)  -- Thanks to James Netwon for this routine --:

apoint1 = apoint1                                                                                              --:

apoint2 = apoint2                                                                                              --:

vDeltaH = aPoint1.locH - aPoint2.locH                                                              --:

vDeltaV = aPoint1.locV - aPoint2.locV                                                              --:

vDelta2 = vDeltaH * vDeltaH + vDeltaV * vDeltaV                                                --:

vDistance = sqrt(float(vDelta2)) --------------------------------------------------------------------------:

add(gVlist,vDistance) -- for use elsewhere, not required here

myimage.draw(gloc1.loch, gloc1.locV, gloc2.loch, gloc2.locv, [linesize: 3, color: rgb(55, 55, 125)] ) --draws the line on the path

gloc1= 0 -- sets to 0 to allow next segment selection

gloc2=0  -- sets to 0 to allow next segment selection

sum1=float(member("distancesum").text) --gets current value of path distance from member

Distance2 = vDistance + sum1 --adds new path distance to old

member("distancesum").text = string(Distance2) -- places distance in on screen member.

end DistanceBetween

Regards,

Rod