Articles Archive
Articles Search
Director Wiki

Dynamic Vector Drawing

July 18, 1999
by Pat McClellan

Dear Multimedia Handyman,

Recent days is not so often I feel like an idiot, but Director 7 vector shapes are driving me mad!

For my application I need to draw lines "on the fly" between moving objects. Vector shapes should be excellent for that task but, unfortunately I've found it is extremaly difficult to control the sprite contaning vector shape: whenever I change the vertex position the registration point of the castmember is being changed and the final location of the sprite does not match the required position any more!

Please provide a behaivior to dynamically draw a line between two moving points using vector graphics.

Zbigniew 'Ziggi' Szczesny

Dear Ziggi,

In this internet age, it shouldn't surprise me to get questions from around the globe. Still, it's really a blast for me to think that our site is having such widespread influence! Thanks for sending in your question.

This challenge gave me a chance to really explore using Vector Shapes and the associated Lingo. They're very powerful, with lots of features to exploit. Since Vectors are not available prior to D7, I'll assume that anyone using this behavior will have upgraded. Therefore, I'm going to start using some of D7's "dot syntax" in my code. I hope it doesn't cause problems for any readers, but you should start getting used to it. Even if you don't use it in your own code, you'll want to know how to read it when others create the code. If you get lost in the dot syntax, consult Zac's article.

Now, on to vectorShapes!

Let's start with the simplest of vector Shapes: a line. You'll remember from your high school geometry class that a line can be defined by its two endpoints. Each point (corner) of a geometric shape is called a vertex, so each end point of a line is called a vertex, plural "vertices". In Director, the vertexList of a vectorShape member is the list of points which define the shape. Note: the vertexList is a member property, not a sprite property.

Try this experiment:

Open D7, open the vector creation window and draw a simple line. Close the window and name your new vector member "Bob". Drag Bob onto the stage in sprite channel 1. Now, in the message window...

put the vertexList of member "Bob"
-- [[#vertex: point(-114.0000, -26.0000)], ¬
  [#vertex: point(114.0000, 27.0000)]]

Of course, your vertex point values will be different from mine.

Now, do this...

put the vertexList of sprite 1

You'll get a "property not found" error message, because vertexList is a property of the vectorShape member, not the sprite. This is critical to our behavior.

Now, here's something else which is important to notice. Take a look at the vertexList. It shows values for 2 points (obviously the end points of our line) but notice that one is the negative value of the other (almost). Why?

Open your vectorShape member in the vector editing window and move one or both of the points. Now, put the vertexList of member "Bob" again. The points have changed, but they're still a mirror image of each other.

This is happening because vectorShape members automatically center their registration point. So, for a line, the registration point will be a point exactly between the two endpoints. So all vertex points are relative to this regPoint. If we alter the vectorShape, a moving regPoint could be very confusing (as you mention in your question.) Luckily, we can set the vectorShape member so that it does not automatically change its regPoint.

set the centerRegPoint of member "Bob" = 0

Now, as we play around altering the points in the vertexList, the sprite won't be moving around the stage unpredictably.

Since we've covered the basic concepts, let's create the behavior which will tether together two sprites, as illustrated in the demo movie below. As you'll see, the Fireworks and Netscape icons are moving on their own with a vector member dynamically adjusting to keep them tethered. The Photoshop and IE icons are similarly tethered, but they don't move on their own. Drag them around to see the effect.

Download a sample movie in Mac or PC format.

The behavior I created for this is really very simple and it gets applied to the vector line sprite. First, I provided for the author to specify the two sprites to be tethered: pFirstSprite and pSecondSprite.

In the beginSprite handler, I'm going to set the centerRegPoint to 0 and establish the regPoint as one of the end points of the line (the first vertex). That means that this first vertex will always be [#vertex: point(0,0)]. Since this end of the line needs to stick with the firstSprite, all we'll need to do is have the loc of the vector sprite follow the loc of the firstsprite.

So on each prepareFrame, we'll reset the loc of our vector sprite to be the same as our firstSprite. Then all we need to do is calculate the relative location of the secondSprite. This is easy to do by simply subtracting the loc of the firstSprite from the loc of the secondSprite. This difference will be the value for the second vertex.

Here's the code:

-- Tether behavior
-- copyright © 1999, ZZP Online, LLC
-- free use for Director Online readers
-- this behavior dynamically connects two 
-- sprites with a vector line
property pFirstSprite
property pSecondSprite
property pSprite
property pMem
on getPropertyDescriptionList me
  set pdlist to [:]
  addprop pdlist, #pFirstSprite, [#comment:"First Sprite", ¬
    #format:#integer, #default:4]
  addprop pdlist, #pSecondSprite, [#comment:"Second Sprite", ¬
    #format:#integer, #default:5]
  return pdlist
end getPropertyDescriptionList
on beginSprite me
  pSprite = sprite the spriteNum of me
  pMem = pSprite.member
  pMem.centerRegPoint = 0
on prepareFrame me
  pSprite.loc = sprite(pFirstSprite).loc
  deltaLoc = sprite(pSecondSprite).loc - sprite(pFirstSprite).loc
  pMem.vertexList = [[#vertex: point(0,0)], [#vertex: deltaLoc]]

Surprisingly easy, right? OK, then... here's some tough stuff!

After playing around with the vectorShapes a bit, I decided to stretch my Lingo wings to create some vector drawing tools. All of the drawing handlers are in one behavior. I won't bother going into all of it here, but you can download the movie to see how I've done things. Note that there have been some bugs with Shockwave and Internet Explorer with regard to mouseDowns and mouseUps. Both of these commands are critical to this behavior, so the demo might not work in your browser.

Download a sample movie in Mac or PC format.

Patrick McClellan is Director Online's co-founder. Pat is Vice President, Managing Director for Jack Morton Worldwide, a global experiential marketing company. He is responsible for the San Francisco office, which helps major technology clients to develop marketing communications programs to reach enterprise and consumer audiences.

Copyright 1997-2019, Director Online. Article content copyright by respective authors.