[Tutor] Button 1 Motion Event
Luke Paireepinart
rabidpoobear at gmail.com
Thu Dec 6 06:38:39 CET 2007
Johnston Jiaa wrote:
>
>> Just don't distinguish between quick and slow drags. Just keep a
>> temporary variable that has the previous mouse position, and draw
>> ovals from there to the current mouse position every time your
>> function is called.
>
> I now have the variable with the previous mouse position. How would I
> draw ovals from the current mouse position to that previous mouse
> position? I tried reasoning it out with a for-loop, but I couldn't
> figure out how to do it.
Well, try reasoning it out with mathematics.
Suppose we have the points (0,0) and (100,100).
What's the slope between these two points?
well, delta-Y is 100 and delta-X is 100, and 100/100 == 1.
This is also the same as 1/1.
Therefore, for every new point we want to get, we'll add 1 to the x
value and 1 to the y value.
Now assume we have the points (23, 45) and (45, 80).
This slope would be:
80 - 45
---------
45 - 23
or 35 / 22.
So as you can see, the number on the top is larger than the number on
the bottom, so our Y-value is increasing more quickly.
But it doesn't really matter which value is bigger, the numerator or the
denominator.
All we care about is the slope. Because slope tells us: this is the
change in Y for every change in X.
The reason slope tells us this is because slope is the ratio between the
change in Y between our 2 points
and the change in X between our 2 points.
Because it's a ratio, it can be applied to any measure, even to
deltaX=1, which gives us what deltaY is.
Since we don't care about any X-coordinates between integers, we don't
care about any other deltaX measurement.
So you'd do something like this:
x = 23.0 # our first points
y = 45.0 # they're float so we can add partial amounts to them.
slope = 35/22.0 # this is float to force float division.
for deltax in range(23, 45):
x += deltax
y += slope
So in this case, each time through the loop, X will move 1 over, and Y
will move slightly more than 1 up.
This still has a problem if the slope is very great in the Y-direction.
Given the case of the points (0,0) and (1,100),
we get a slope of 100. Thus, we will draw points at 0,0 and at 1,100
and none in-between,
when realistically we'd like at least a vertical line between them, or
preferably one that shifts one pixel over halfway-up.
Note that the poitns (0,0) and (100, 1) would not create a problem.
This is because our delta-x is changing at a set rate,
and our deltay is a smaller number. It would work in this case.
What's creating the problem is that our slope is greater than 1, and
we're using delta-x as a fixed amount.
If we add the condition that we affix delta-x to the value 1 for slopes
less than 1, and delta-y to 1 when slopes are greater than 1,
then everything should work out perfectly. The case of slope == 1 will
be correctly handled in either case, just make sure to include it in one
of them.
Thusly, our code would look something like this:
point1x, point1y = raw_input("please input the first pair of coordinates
separated by a space: ").split(' ')
point2x, point2y = raw_input("please input the second pair of
coordinates separated by a space: ").split(' ')
slope = (point2y - point1y) / (float(point2x - point1x))
if slope > 1:
deltax = 1 / slope # i assume we invert slope here?
deltay = 1
else:
deltax = 1
deltay = slope
currentx = float(point1x)
currenty = float(point1y)
for x in range(max((point2y - point1y), (point2x - point1x)) ):
#we choose our range as the larger of the two lengths.
#thus if delta-x is only 1px and delta-y is 100px, we'll
#still draw all those points in between.
# ..........
# draw the currentx, currenty point here
# .........
currentx += deltax
currenty += deltay
# and draw the point one more time here, to get your ending point.
Note that I don't profess that either my code or my math is correct; I
didn't test any of this, it's more to give you an idea of how to
approach Computer Science problems.
>
> Also, I need to be able to save the canvas drawing. Would it be
> possible to write some sort of data to a file that could be used to
> load the previously saved drawing back onto the canvas?
You can just keep a cache of all points and redraw them on load, or you
can dump it out to an image file. I believe TKInter supports that, but
I haven't used that library in a long time.
Again, _please reply on-list_ unless you want a discussion to be
private, in which case specify in the e-mail so we know it wasn't an
accident.
-Luke
More information about the Tutor
mailing list