all right hello everyone and welcome to
this
year 3 49 lecture about drawing and
manipulating graphics
in javafx
so until now we've just learned to
draw primitives but for more complex
shapes we
need a model we can use principles from
computer graphics to define
our ui elements so a model is
the data structure that represents our
image
and all its properties the rendering
process
of the model is the process that uses
the model and its properties to create
an image
to display on screen and the image is is
then the result
of the rendered model
so javafx uses a shape model
to represent primitive shapes a shape is
an array
of points that we connect we connect to
draw shape
and the shape has drawing properties
like the fill color the stroke thickness
and corner
if the shape is closed or not if it's
filled and etc
so shape models are useful
to manipulate the shapes dynamically
we can then easily translate them rotate
or scale them
and also create multiple instances of
the shape
the shape model is in a base coordinate
frame
and the model is transformed before
rendering the basic transformations are
translation
rotation and scale
so the translation
is the process of adding and
a scanner a number two coordinates
here we add two to the x component and
four to the y
coordinate okay
so uniform scaling is done by
multiplying each coordinate
component by the same scanner same
number
so here for example we uniformly scaled
the object by a factor of two so
meaning that we double the size of the
object
so you also have non uniform scaling
it's when the scale factor is not the
same for
every coordinate component here we
double the size
in the x component but divide its
y component by 2.
the rotation transformation in 2d is a
more complex
function involving a pivot point
and an angle so let's see
at first our object position is that
upon
x y or r
times cos phi and our time sin phi
in polar coordinates when we rotate the
object
around the origin by a theta and angle
the new polar coordinates are r
times question is the sum of phi
and theta and all time sinus of phi
and and theta all right
so using these uh identities
we can replace the cosine of phi and
theta
by r times cos phi time
times cos theta minus r times
sinus phi times sinister
and with 1 and 2
this reduces to x times
cos theta minus y times center
the same goes for the y-coordinate
okay so
now we know that a 30 degrees rotation
around the origin is given by these
functions okay if you have to remember
one thing
is this okay so obviously you can
combine transformations
um so first let's uniformly
scale our home by two okay
then rotate it by 30 degrees
and then translate it and try to apply
this
the the same operation in a different
order and you won't have the same
results
right so keep in mind that your the
order is important here
okay so you can define your own
transform
functions for example here the translate
function takes a polygon object and add
and two translation coordinates and
apply them to
all the points in the polygon right so
this is a handmade translate function
for
a polygon object
but you can also use the built-in
functions
that the shape class provides and that
is the base class of most of the shape
objects in javafx
so note that the scale translate and
rotation factors
are attributes in the shape methods
right we are using set scale eggs
citrons like
x etc so you set
those attributes but you don't actually
scale
um immediately the transformation
is made during the rendering process
and is always done in the same order so
you can set scale
and translate in all in another order
and you will render the same result
you can also apply transformation
directly using the graphics context
using for example translate and scale
method but here the transformations are
made
at the core of the function so the
the order does matter here also
translate applies to the graphics
context not directly to the shape
so the transformations accumulate if you
want to draw a shape that is not scaled
after the last film wrecked function
you should discard the last scale
function
by applying the reverse operations
so javafx also lets you transform a
whole
group of shapes contained under a common
node
okay so in the scene graph the children
inherit from their parents
transformation and can add their own
in the first example shape one and two
will all be rotated
by 15 degrees
so now that we know how to transform
shapes
um either using the transformation
attributes in shape or using the graphic
context
and now we're gonna see how we can
determine if point is
in the shape it's called hit tests right
which refers to collision detection
so this is useful to implement uh direct
manipulation if we want to be able to
select objects using
a mouse we need to have a way of
knowing if the mouse is on the object or
or new to it a selection paradigm is
is how you select objects and
implement the heat test then respond to
the selection
event
in drawing application applications you
have different selection paradigms
selection of shapes can be made by
directly pointing and clicking
on the shape to do this
we would use inside and outside heat
tests
um open shapes like lines
would use edge heat test white for
closed
shapes um heat tests consist in
determining if
a point in this inside the shape if the
click
happen inside the shape other selection
paradigms like the rubber band
or the lasso are popular and they select
the shapes that are contained
in a shape drawn by the user
you can either implement your custom
shape classes with their own hit method
that returns if a point hit the shape
or you can use the built-in methods
that java effects in the javafx classes
so let's see an example for the custom
shapes
rectangle and circle a rectangle is
defined
by four points and let x and y
be the coordinates of our my mouse
pointer
all right the rectangle is then selected
if
x is greater than x1
but lower than x2 and n
if y is greater than y1 and lower down
y2 for the circle with
p2 being our mouse click the circle is
selected if the distance between
p1 and the center of our social is lower
down the radius
of the circle okay
so this is pretty simple for now
for the line it becomes a bit more
complex since it can be
a diagonal so the solution is to compute
the closest point
of the line on the line to the mouse
pointer coordinates
right then to calculate the distance
between
those two points and if the distance
is lower than a defined threshold then
the line is selected
so in order to compute the closest point
we use vector
vector projection let's see how it works
so we have two points p0 and p1
that are part of the line and m is
a point to project orthogonally on the
line
okay so first we compute the vector v
that represents the line and test for
its length
to be higher than one pixel long
then we compute the vector p1 m
and let's call it u
we then use the dot product of u by v
to project the vector u on vector v
all right we normalize by the norm
of v because v might not be a unique
vector
then depending on the sign of the
projection which is a scanner
we either return p0 which means that the
closest point to m
on the line is p0 or p1 if the projector
projection is higher than one
if it's between 0 and 1 this means that
the closest point to m is between
p0 and p1 on the line this is given by
multiplying
v by the projections color and add it to
p0
all right it's it's basic
algebra and i recommend
drawing the this example if it's a bit
effective for you
so we can see that it's possible to
implement a custom shape
heat test methods for rectangles circles
and lines
but for more complex shapes it becomes
more and more difficult
but the good news is that javafx does
provide a hit method for every shape
surpluses like rectangles
circles or even polygons and this method
is called contains
right so for example here we can see
that circle rectangle
rectangle ellipse and polygons
have contains method
you just have to give it a point objects
so that the contains methods exist
also for the polygon object which is
make it which makes it
really easy and in order to know if the
mouse clicked
on the shape we just have to pass the
mouse event
coordinates to the contains method of
our shape
here to on our polygon right
so if it returns true then it hits um
the the polygon and we can do whatever
we want to do when a selection happens
for example here we just change the
corner of the shape to blue
otherwise we change it to red okay
another way to handle clicks and mouse
clicks
is to directly implement the
almost clicked even handler that is
built in
in any shape subclasses here for a house
polygon
we set a mouse clicked event handler
that prints
the mouse coordinates and change the
color to blue
we also set the mouse clicked handler of
the group containing the house
so that when it's clicked
when it's clicked the house will turn
red
and the way even so handled is that
when an event happens for example a
click
the event will be propagated in the
scene graph into the nodes that contains
the mouse events and the last node that
contains the mouse click
will be the one from which the event
handler will be called if set
okay and if no handler is set
then we'll use the parent
parent node
okay so that was for the hit test
and let's talk about animation now so
animations are including javax
effects but let's see first what is an
animation
so it is a simulation of a movement
created by displaying a series of
pictures
of frames at a controlled rate
the standard rate for film was 24 fps
at the beginning it's 60 fps
so frames per second for tv
and around 60 fps for games
friends can all be supplied but usually
frames are
derived from two other frames by
interpolation
okay some vocabulary vocabulary before
we continue
a frame is one image in the animation
the frame rate is the number of frames
displayed per second
and the keyframe is a frame at the point
in time
of the animation okay
so in javafx you can manually control an
animation
thanks to animation timer that calls the
animation method
at a regular time interval the timer
runs on
separate thread and only fires the
handle
function when the time has come here
the ball the red circle will move of
dx and dy every time the animation
timer fires so if we want a 60
fps animation the bone will move every
1000 divided by 60
equal to 17 milliseconds so
the ball will have to move every 17
milliseconds
so this is if we want to manually
control
our animation but javafx also includes
helping
functions to animate our nodes it exists
all kinds of animations called
transitions
it is not just to move an object uh it's
also to change its color or its rotation
or scale depending on what you want you
can have different
um you have different names for the for
the transition
so let's see an example of translation
transition
in the scene we have a button and an
image view we create a translation
animation called transition
that only applies to button with a
duration
of 2 seconds and a half ok
then we set by how much we want the
translation to
move the button here 200 on x
and 100 on y we then set a
count of two cycles which means that
we're gonna
repeat the animation twice and then
the button should go back to the
beginning position
on the second part of the animation
so finally we set an action listener for
click that starts the animation whenever
the button is clicked
this is the play function here
right so this is for really simple
animation
and for more complex ones you might need
to use the keyframes timeline
classes keyframes are point in time that
defines the value to be made
by the animation here we attach
the timeline object to every circle
in the in the scene graph and in
in the group sorry the first
one so the timeline has two keyframes
the first one
uh is a keyframe at the start position
because of the duration zero parameter
so the first parameter is the time in
the animation the key values
are the values that the animation should
meet
the first key value is the translation
of the current circle along the x-axis
of 800 times a random number
the second key value is a translation
of the circle on the y-axis by an amount
of
600 times a random number as well
and finally we have a second keyframe
and in it that it's added
after four seconds and this timeline
means that between the start
and the end of the animation the longest
4 seconds
the current source the current circle
will move along the x and y
axis the animation interpolates between
the two keyframes
you don't have to to do it you can add
as many keyframes as needed in a
timeline
so this covers most of the 2d graphics
graphics stuff that we'll need in this
course
some details about combining
transformations will be given
in the next lecture