SlideShare a Scribd company logo
1 of 28
Download to read offline
Computer Graphics
in Java and Scala
Part 1b
first see the Scala program translated into Java
then see the Scala program modified to produce a more intricate drawing
@philip_schwarz
slides by https://www.slideshare.net/pjschwarz
In this slide deck, which is an addendum to Part 1, we are going to do the following:
• Translate the Scala program from Part 1 into Java
• Modify the Scala program so that rather than drawing 50 concentric triangles, it draws a
chessboard-like grid in which each cell consists of 10 concentric squares.
• Eliminate an unsatisfactory feature of the above drawing by changing the angle by which
squares are twisted, plus improve the drawing by increasing the number of squares drawn.
case class Point(x: Float, y: Float)
object Triangle:
def apply(centre:Point,side:Float,height:Float): Triangle =
val Point(x,y) = centre
val halfSide = 0.5F * side
val bottomLeft = Point(x - halfSide, y - 0.5F * height)
val bottomRight = Point(x + halfSide, y - 0.5F * height)
val top = Point(x, y + 0.5F * height )
Triangle(bottomLeft,bottomRight,top)
case class Triangle(a: Point, b: Point, c: Point) public record Triangle(Point a, Point b, Point c) {
static Triangle instance(Point centre,Float side,Float height) {
float x = centre.x(), y = centre.y();
var halfSide = 0.5F * side;
var bottomLeft = new Point(x - halfSide, y - 0.5F * height);
var bottomRight = new Point(x + halfSide, y - 0.5F * height);
var top = new Point(x, y + 0.5F * height);
return new Triangle(bottomLeft,bottomRight,top);
}
}
public record Point(Float x, Float y) { }
Let’s start translating the
Scala program into Java.
@philip_schwarz
LazyList
.iterate(triangle)(shrinkAndTwist)
.take(50)
.foreach(draw)
Stream
.iterate(triangle, this::shrinkAndTwist)
.limit(50)
.forEach(t -> draw(g, t, panelHeight));
class TrianglesPanel extends JPanel:
setBackground(Color.white)
override def paintComponent(g: Graphics): Unit =
super.paintComponent(g)
val panelSize: Dimension = getSize()
val panelWidth = panelSize.width - 1
val panelHeight = panelSize.height - 1
val panelCentre = Point(panelWidth / 2, panelHeight / 2)
val triangleSide = 0.95F * Math.min(panelWidth, panelHeight)
val triangleHeight = (0.5F * triangleSide) * Math.sqrt(3).toFloat
…<shrinkAndTwist, draw and drawLine functions>…
val triangle = Triangle(panelCentre,
triangleSide,
triangleHeight)
LazyList
.iterate(triangle)(shrinkAndTwist)
.take(50)
.foreach(draw)
public class TrianglesPanel extends JPanel {
public TrianglesPanel() {
setBackground(Color.white);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Dimension panelSize = getSize();
int panelWidth = panelSize.width - 1;
int panelHeight = panelSize.height - 1;
var panelCentre = new Point(panelWidth / 2F, panelHeight / 2F);
var triangleSide = 0.95F * Math.min(panelWidth, panelHeight);
var triangleHeight = (0.5F * triangleSide) * (float)Math.sqrt(3);
var triangle = Triangle.instance(panelCentre,
triangleSide,
triangleHeight);
Stream
.iterate(triangle, this::shrinkAndTwist)
.limit(50)
.forEach(t -> draw(g, t, panelHeight));
}
…<shrinkAndTwist, draw and drawLine functions>…
}
val shrinkAndTwist: Triangle => Triangle =
val q = 0.05F
val p = 1 - q
def combine(a: Point, b: Point) =
Point(p * a.x + q * b.x, p * a.y + q * b.y)
{ case Triangle(a,b,c) =>
Triangle(combine(a,b), combine(b,c), combine(c,a)) }
Triangle shrinkAndTwist(Triangle t) {
return new Triangle(
combine(t.a(), t.b()),
combine(t.b(), t.c()),
combine(t.c(), t.a())
);
}
Point combine(Point a, Point b) {
var q = 0.05F;
var p = 1 - q;
return new Point(p * a.x() + q * b.x(), p * a.y() + q * b.y());
}
val draw: Triangle => Unit =
case Triangle(a, b, c) =>
drawLine(a, b)
drawLine(b, c)
drawLine(c, a)
def drawLine(a: Point, b: Point): Unit =
val (ax,ay) = a.deviceCoords(panelHeight)
val (bx,by) = b.deviceCoords(panelHeight)
g.drawLine(ax, ay, bx, by)
void draw(Graphics g, Triangle t, int panelHeight) {
drawLine(g, t.a(), t.b(), panelHeight);
drawLine(g, t.b(), t.c(), panelHeight);
drawLine(g, t.c(), t.a(), panelHeight);
}
void drawLine(Graphics g, Point a, Point b, int panelHeight) {
var aCoords = deviceCoords(a, panelHeight);
var bCoords = deviceCoords(b, panelHeight);
int ax = aCoords.x, ay = aCoords.y, bx = bCoords.x, by = bCoords.y;
g.drawLine(ax, ay, bx, by);
}
java.awt.Point deviceCoords(Point p, int panelHeight) {
return new java.awt.Point(Math.round(p.x()), panelHeight - Math.round(p.y()));
}
extension (p: Point)
def deviceCoords(panelHeight: Int): (Int, Int) =
(Math.round(p.x), panelHeight - Math.round(p.y))
class Triangles:
JFrame.setDefaultLookAndFeelDecorated(true)
val frame =
new JFrame("Triangles: 50 triangles inside each other")
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
frame.setSize(600, 400)
frame.add(TrianglesPanel())
frame.setVisible(true)
@main def main: Unit =
// Create a frame/panel on the event dispatching thread
SwingUtilities.invokeLater(
new Runnable():
def run: Unit = Triangles()
)
public class Triangles {
public static void main(String[] args) {
// Create a frame/panel on the event dispatching thread
SwingUtilities.invokeLater(
() -> new Triangles().drawTriangles()
);
}
void drawTriangles() {
JFrame.setDefaultLookAndFeelDecorated(true);
var frame = new JFrame("Triangles: 50 triangles inside each other");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(600, 400);
frame.add(new TrianglesPanel());
frame.setVisible(true);
}
}
On the next slide we check that the
Java program works as intended.
Now we turn to an exercise that sees us modify the Scala program so that
rather than drawing 50 concentric triangles, it draws a chessboard-like
grid in which each cell consists of 10 concentric squares.
Exercises
…
1.2 Replace the triangles of program Triangles.java with squares and draw a great many of them, arranged in a
chessboard, as show in Fig 1.11.
As usual, this chessboard, consists of 𝑛 × 𝑛 normal squares (with horizontal and vertical edges), where 𝑛 = 8.
Each of these actually consists of 𝑘 squares of different sizes, with 𝑘 = 10.
Finally, the value 𝑞 = 0.2 (and 𝑝 = 1 − 𝑞 = 0.8) was used to divide each edge into two parts with ratio 𝑝 ∶ 𝑞 (see also
program Triangles.java of section 1.2), but the interesting pattern of Fig 1.11 was obtained by reversing the roles of
𝑝 and 𝑞 in half of the 𝑛 × 𝑛 ‘normal’ squares, which is similar to the black and white squares of a normal chessboard.
Your program should accept the values 𝑛, 𝑘 and 𝑞 as program arguments.
Figure 1.11 A chessboard of squares
On the next slide we start modifying the Scala program so that
it meets the new requirements (though we are not going to
bother getting the program to accept 𝑛, 𝑘 and 𝑞 as parameters).
@philip_schwarz
object Triangle:
def apply(centre: Point, side: Float, height: Float): Triangle =
val Point(x,y) = centre
val halfSide = 0.5F * side
val bottomLeft = Point(x - halfSide, y - 0.5F * height)
val bottomRight = Point(x + halfSide, y - 0.5F * height)
val top = Point(x, y + 0.5F * height )
Triangle(bottomLeft,bottomRight,top)
case class Triangle(a: Point, b: Point, c: Point) case class Square(a: Point, b: Point, c: Point, d: Point)
object Square:
def apply(centre: Point, side: Float): Square =
val Point(x,y) = centre
val halfSide = 0.5F * side
val bottomLeft = Point(x - halfSide, y - halfSide)
val bottomRight = Point(x + halfSide, y - halfSide)
val topRight = Point(x + halfSide, y + halfSide)
val topLeft = Point(x - halfSide, y + halfSide)
Square(bottomLeft,bottomRight,topRight,topLeft)
LazyList
.iterate(triangle)(shrinkAndTwist)
.take(50)
.foreach(draw)
for
(row, startDirection) <- (0 until gridSize)
zip alternatingDirections(Direction.Right)
(col, twistDirection) <- (0 until gridSize)
zip alternatingDirections(startDirection)
square = Square(squareCentre(row,col),squareSide)
yield LazyList
.iterate(square)(shrinkAndTwist(twistDirection))
.take(10)
.foreach(draw)
def squareCentre(row: Int, col: Int): Point =
Point(panelCentre.x-(gridSize/2*squareSide)+(col*squareSide)+squareSide/2,
panelCentre.y-(gridSize/2*squareSide)+(row*squareSide)+squareSide/2)
enum Direction:
case Left, Right
def reversed: Direction = if this == Right then Left else Right
def alternatingDirections(startDirection: Direction): LazyList[Direction] =
LazyList.iterate(startDirection)(_.reversed)
We are going to use a for comprehension to work through each of the 64 cells in the 8 × 8 grid,
ensuring that each time we move from one cell to the next, we invert the direction (right = clockwise
and left = counterclockwise) in which we twist the concentric squares drawn within a cell.
object TrianglesPanel extends JPanel:
setBackground(Color.white)
override def paintComponent(g: Graphics): Unit =
super.paintComponent(g)
val panelSize: Dimension = getSize()
val panelWidth = panelSize.width - 1
val panelHeight = panelSize.height - 1
val panelCentre = Point(panelWidth / 2, panelHeight / 2)
val triangleSide = 0.95F * Math.min(panelWidth, panelHeight)
val triangleHeight = (0.5F * triangleSide) * Math.sqrt(3).toFloat
…<shrinkAndTwist, draw and drawLine functions>…
val triangle = Triangle(panelCentre,
triangleSide,
triangleHeight)
LazyList
.iterate(triangle)(shrinkAndTwist)
.take(50)
.foreach(draw)
object SquaresPanel extends JPanel:
setBackground(Color.white)
override def paintComponent(g: Graphics): Unit =
super.paintComponent(g)
val panelSize: Dimension = getSize()
val panelWidth = panelSize.width - 1
val panelHeight = panelSize.height - 1
val panelCentre = Point(panelWidth / 2, panelHeight / 2)
val gridSize = 8
val squareSide: Float = 0.95F * Math.min(panelWidth, panelHeight) / gridSize
…<shrinkAndTwist, draw and drawLine functions>…
def squareCentre(row: Int, col: Int): Point =
Point(panelCentre.x-(gridSize/2*squareSide)+(col*squareSide)+squareSide/2,
panelCentre.y-(gridSize/2*squareSide)+(row*squareSide)+squareSide/2)
for
(row, startDirection) <- (0 until gridSize)
zip alternatingDirections(Direction.Right)
(col, twistDirection) <- (0 until gridSize)
zip alternatingDirections(startDirection)
square = Square(squareCentre(row,col),squareSide)
yield LazyList
.iterate(square)(shrinkAndTwist(twistDirection))
.take(10)
.foreach(draw)
val shrinkAndTwist: Triangle => Triangle =
val q = 0.05F
val p = 1 - q
def combine(a: Point, b: Point) =
Point(p * a.x + q * b.x, p * a.y + q * b.y)
{ case Triangle(a,b,c) =>
Triangle(
combine(a,b),
combine(b,c),
combine(c,a)) }
val draw: Triangle => Unit =
case Triangle(a, b, c) =>
drawLine(a, b)
drawLine(b, c)
drawLine(c, a)
def drawLine(a: Point, b: Point): Unit =
val (ax,ay) = a.deviceCoords(panelHeight)
val (bx,by) = b.deviceCoords(panelHeight)
g.drawLine(ax, ay, bx, by)
def shrinkAndTwist(direction: Direction): Square => Square =
val q = if direction == Direction.Right then 0.2F else 0.8F
val p = 1 - q
def combine(a: Point, b: Point) =
Point(p * a.x + q * b.x, p * a.y + q * b.y)
{ case Square(a,b,c,d) =>
Square(
combine(a,b),
combine(b,c),
combine(c,d),
combine(d,a)) }
def drawLine(a: Point, b: Point): Unit =
val (ax,ay) = a.deviceCoords(panelHeight)
val (bx,by) = b.deviceCoords(panelHeight)
g.drawLine(ax, ay, bx, by)
val draw: Square => Unit =
case Square(a, b, c, d) =>
drawLine(a, b)
drawLine(b, c)
drawLine(c, d)
drawLine(d, a)
def drawTriangles: Unit =
JFrame.setDefaultLookAndFeelDecorated(true)
val frame =
new JFrame("Triangles: 50 triangles inside each other")
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE)
frame.setSize(600, 400)
frame.add(TrianglesPanel)
frame.setVisible(true)
@main def trianglesMain: Unit =
// Create the frame/panel on the event dispatching thread
SwingUtilities.invokeLater(
new Runnable():
def run: Unit = drawTriangles
)
def drawSquares: Unit =
JFrame.setDefaultLookAndFeelDecorated(true)
val frame =
new JFrame("A chessboard of squares")
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE)
frame.setSize(600, 400)
frame.add(SquaresPanel)
frame.setVisible(true)
@main def squaresMain: Unit =
// Create the frame/panel on the event dispatching thread
SwingUtilities.invokeLater(
new Runnable():
def run: Unit = drawSquares
)
On the next slide we have a go at
running the modified Scala program.
That’s nice, but it turns out that there is an unsatisfactory feature
in that drawing: we can improve the drawing by removing that
feature and increasing the number of squares drawn.
@philip_schwarz
This idea is further illustrated by drawing the pattern shown in figure 3.3a.
At first sight it looks complicated, but on closer inspection it is seen to be simply a square, outside a square,
outside a square etc.
The squares are getting successively smaller and they are rotating through a constant angle. In order to draw
the diagram, a technique is needed which, when given a general square, draws a smaller internal square
rotated through this fixed angle.
Suppose the general square has corners {(xi , yi) | i = 1, 2, 3, 4} and the i th side of the square is the line joining
(xi , yi) to (xi+1 , yi+1) - assuming additions of subscripts are modulo 4 - that is, 4 + 1 ≡ 1.
A general point on this side of the square, (x’i , y’i), is given by
((1	- 𝜇)	× xi		+	𝜇 × xi+1,	(1	- 𝜇)	× yi +	𝜇 × yi+1) where 0 ≤ 𝜇 ≤ 1
In fact 𝜇 : 1 - 𝜇 is the ratio in which the side is cut by this point. If 𝜇 is fixed and the four points {(xi , yi) | i = 1, 2,
3, 4} are calculated in the above manner, then the sides of the new square make an angle
𝛼 = tan-1[𝜇/(1 -𝜇)]
with the corresponding side of the outer square. So by keeping 𝜇 fixed for each new square, the angle between
consecutive squares remains constant at 𝛼. In figure 3.3a … there are 21 squares and 𝜇 = 0.1.
There is an unsatisfactory feature of the pattern in figure 3.3a: the inside of the pattern is 'untidy', the sides of
the innermost square being neither parallel to nor at 𝜋/4 radians to the corresponding side of the outermost
square.
This is corrected simply by changing the value of 𝜇 so as to produce the required relationship between the
innermost and outermost squares.
As was previously noted, with the calculation of each new inner square, the corresponding sides are rotated
through an angle of tan−1[𝜇/(1 −𝜇)] radians.
After 𝑛 + 1 squares are drawn, the inner square is rotated by 𝑛 × tan−1[𝜇/(1 −𝜇)] radians relative to the outer
square. For a satisfactory diagram this angle must be an integer multiple of 𝜋/4.
That is, 𝑛 × tan−1[𝜇/(1 −𝜇)] = t(𝜋/4) for some integer t, and hence
𝜇 =
tan[t(𝜋/4n)]
tan[t(𝜋/4n)]+1
To produce figure 3.3b, 𝑛 = 20 and t = 3 are chosen.
val mu: Float =
val t = 3
val x = Math.tan(t * (Math.PI/(4 * squareCount)))
(x / (x + 1)).toFloat
def shrinkAndTwist(direction: Direction): Square => Square =
val q = if direction == Direction.Right then 0.2F else 0.8F
val p = 1 - q
def combine(a: Point, b: Point) =
Point(p * a.x + q * b.x, p * a.y + q * b.y)
{ case Square(a,b,c,d) =>
Square(
combine(a,b),
combine(b,c),
combine(c,d),
combine(d,a)) }
def shrinkAndTwist(direction: Direction): Square => Square =
val q = if direction == Direction.Right then mu else 1 - mu
val p = 1 - q
def combine(a: Point, b: Point) =
Point(p * a.x + q * b.x, p * a.y + q * b.y)
{ case Square(a,b,c,d) =>
Square(
combine(a,b),
combine(b,c),
combine(c,d),
combine(d,a)) }
val squareCount = 20
LazyList
.iterate(square)(shrinkAndTwist(twistDirection))
.take(10)
.foreach(draw)
LazyList
.iterate(square)(shrinkAndTwist(twistDirection))
.take(squareCount + 1)
.foreach(draw)
Let’ run the improved
Scala program.
Before and after the improvements
That’s all. I hope
you enjoyed that.
@philip_schwarz

More Related Content

What's hot

Computer graphics lab report with code in cpp
Computer graphics lab report with code in cppComputer graphics lab report with code in cpp
Computer graphics lab report with code in cppAlamgir Hossain
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Languagevsssuresh
 
Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsPhilip Schwarz
 
Matlab practice
Matlab practiceMatlab practice
Matlab practiceZunAib Ali
 
Matlab plotting
Matlab plottingMatlab plotting
Matlab plottingAmr Rashed
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1Philip Schwarz
 
Computer graphics practical(jainam)
Computer graphics practical(jainam)Computer graphics practical(jainam)
Computer graphics practical(jainam)JAINAM KAPADIYA
 
A mid point ellipse drawing algorithm on a hexagonal grid
A mid  point ellipse drawing algorithm on a hexagonal gridA mid  point ellipse drawing algorithm on a hexagonal grid
A mid point ellipse drawing algorithm on a hexagonal gridS M K
 
Chapter 1: Linear Regression
Chapter 1: Linear RegressionChapter 1: Linear Regression
Chapter 1: Linear RegressionAkmelSyed
 
Unit 2
Unit 2Unit 2
Unit 2ypnrao
 
Java applet handouts
Java applet handoutsJava applet handouts
Java applet handoutsiamkim
 
Class program and uml in c++
Class program and uml in c++Class program and uml in c++
Class program and uml in c++Osama Al-Mohaia
 

What's hot (20)

Matlab plotting
Matlab plottingMatlab plotting
Matlab plotting
 
Computer graphics lab report with code in cpp
Computer graphics lab report with code in cppComputer graphics lab report with code in cpp
Computer graphics lab report with code in cpp
 
Graph Plots in Matlab
Graph Plots in MatlabGraph Plots in Matlab
Graph Plots in Matlab
 
Cgm Lab Manual
Cgm Lab ManualCgm Lab Manual
Cgm Lab Manual
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
 
Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generators
 
Mat lab
Mat labMat lab
Mat lab
 
Matlab practice
Matlab practiceMatlab practice
Matlab practice
 
Matlab plotting
Matlab plottingMatlab plotting
Matlab plotting
 
Monad Transformers - Part 1
Monad Transformers - Part 1Monad Transformers - Part 1
Monad Transformers - Part 1
 
Computer graphics practical(jainam)
Computer graphics practical(jainam)Computer graphics practical(jainam)
Computer graphics practical(jainam)
 
Programming with matlab session 6
Programming with matlab session 6Programming with matlab session 6
Programming with matlab session 6
 
A mid point ellipse drawing algorithm on a hexagonal grid
A mid  point ellipse drawing algorithm on a hexagonal gridA mid  point ellipse drawing algorithm on a hexagonal grid
A mid point ellipse drawing algorithm on a hexagonal grid
 
Chapter 1: Linear Regression
Chapter 1: Linear RegressionChapter 1: Linear Regression
Chapter 1: Linear Regression
 
Computer graphics
Computer graphicsComputer graphics
Computer graphics
 
Unit 2
Unit 2Unit 2
Unit 2
 
Java applet handouts
Java applet handoutsJava applet handouts
Java applet handouts
 
Class program and uml in c++
Class program and uml in c++Class program and uml in c++
Class program and uml in c++
 
Monad Fact #2
Monad Fact #2Monad Fact #2
Monad Fact #2
 
Computer graphics
Computer graphics   Computer graphics
Computer graphics
 

Similar to Computer Graphics in Java and Scala - Part 1b

MATLAB for Technical Computing
MATLAB for Technical ComputingMATLAB for Technical Computing
MATLAB for Technical ComputingNaveed Rehman
 
ImplementDijkstra’s algorithm using the graph class you implemente.pdf
ImplementDijkstra’s algorithm using the graph class you implemente.pdfImplementDijkstra’s algorithm using the graph class you implemente.pdf
ImplementDijkstra’s algorithm using the graph class you implemente.pdfgopalk44
 
More instructions for the lab write-up1) You are not obli.docx
More instructions for the lab write-up1) You are not obli.docxMore instructions for the lab write-up1) You are not obli.docx
More instructions for the lab write-up1) You are not obli.docxgilpinleeanna
 
Intro to Python (High School) Unit #3
Intro to Python (High School) Unit #3Intro to Python (High School) Unit #3
Intro to Python (High School) Unit #3Jay Coskey
 
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxSAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxagnesdcarey33086
 
Lec 9 05_sept [compatibility mode]
Lec 9 05_sept [compatibility mode]Lec 9 05_sept [compatibility mode]
Lec 9 05_sept [compatibility mode]Palak Sanghani
 
Intro to Matlab programming
Intro to Matlab programmingIntro to Matlab programming
Intro to Matlab programmingAhmed Moawad
 
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxSAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxanhlodge
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
CS 354 Transformation, Clipping, and Culling
CS 354 Transformation, Clipping, and CullingCS 354 Transformation, Clipping, and Culling
CS 354 Transformation, Clipping, and CullingMark Kilgard
 
XIX PUG-PE - Pygame game development
XIX PUG-PE - Pygame game developmentXIX PUG-PE - Pygame game development
XIX PUG-PE - Pygame game developmentmatheuscmpm
 
INTRODUCTION TO MATLAB presentation.pptx
INTRODUCTION TO MATLAB presentation.pptxINTRODUCTION TO MATLAB presentation.pptx
INTRODUCTION TO MATLAB presentation.pptxDevaraj Chilakala
 
Creating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfCreating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfShaiAlmog1
 
Introduction to Neural Networks and Deep Learning from Scratch
Introduction to Neural Networks and Deep Learning from ScratchIntroduction to Neural Networks and Deep Learning from Scratch
Introduction to Neural Networks and Deep Learning from ScratchAhmed BESBES
 

Similar to Computer Graphics in Java and Scala - Part 1b (20)

MATLAB for Technical Computing
MATLAB for Technical ComputingMATLAB for Technical Computing
MATLAB for Technical Computing
 
ImplementDijkstra’s algorithm using the graph class you implemente.pdf
ImplementDijkstra’s algorithm using the graph class you implemente.pdfImplementDijkstra’s algorithm using the graph class you implemente.pdf
ImplementDijkstra’s algorithm using the graph class you implemente.pdf
 
More instructions for the lab write-up1) You are not obli.docx
More instructions for the lab write-up1) You are not obli.docxMore instructions for the lab write-up1) You are not obli.docx
More instructions for the lab write-up1) You are not obli.docx
 
MATLABgraphPlotting.pptx
MATLABgraphPlotting.pptxMATLABgraphPlotting.pptx
MATLABgraphPlotting.pptx
 
Intro to Python (High School) Unit #3
Intro to Python (High School) Unit #3Intro to Python (High School) Unit #3
Intro to Python (High School) Unit #3
 
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxSAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
 
Lesson 3
Lesson 3Lesson 3
Lesson 3
 
Lec 9 05_sept [compatibility mode]
Lec 9 05_sept [compatibility mode]Lec 9 05_sept [compatibility mode]
Lec 9 05_sept [compatibility mode]
 
Intro to Matlab programming
Intro to Matlab programmingIntro to Matlab programming
Intro to Matlab programming
 
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxSAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
 
Monadologie
MonadologieMonadologie
Monadologie
 
CS 354 Transformation, Clipping, and Culling
CS 354 Transformation, Clipping, and CullingCS 354 Transformation, Clipping, and Culling
CS 354 Transformation, Clipping, and Culling
 
XIX PUG-PE - Pygame game development
XIX PUG-PE - Pygame game developmentXIX PUG-PE - Pygame game development
XIX PUG-PE - Pygame game development
 
lect.no.3.pptx
lect.no.3.pptxlect.no.3.pptx
lect.no.3.pptx
 
Scmad Chapter06
Scmad Chapter06Scmad Chapter06
Scmad Chapter06
 
INTRODUCTION TO MATLAB presentation.pptx
INTRODUCTION TO MATLAB presentation.pptxINTRODUCTION TO MATLAB presentation.pptx
INTRODUCTION TO MATLAB presentation.pptx
 
Matlab1
Matlab1Matlab1
Matlab1
 
Creating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdfCreating an Uber Clone - Part IV - Transcript.pdf
Creating an Uber Clone - Part IV - Transcript.pdf
 
Introduction to Neural Networks and Deep Learning from Scratch
Introduction to Neural Networks and Deep Learning from ScratchIntroduction to Neural Networks and Deep Learning from Scratch
Introduction to Neural Networks and Deep Learning from Scratch
 
Maps
MapsMaps
Maps
 

More from Philip Schwarz

Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Folding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesFolding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesPhilip Schwarz
 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesPhilip Schwarz
 
Folding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesFolding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesPhilip Schwarz
 
Scala Left Fold Parallelisation - Three Approaches
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three ApproachesPhilip Schwarz
 
Tagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsTagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsPhilip Schwarz
 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsPhilip Schwarz
 
A sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaA sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaPhilip Schwarz
 
A sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaA sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaPhilip Schwarz
 
A sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaA sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaPhilip Schwarz
 
N-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsPhilip Schwarz
 
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Philip Schwarz
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...Philip Schwarz
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an examplePhilip Schwarz
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an examplePhilip Schwarz
 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...Philip Schwarz
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...Philip Schwarz
 
Jordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsJordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsPhilip Schwarz
 

More from Philip Schwarz (20)

Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Folding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a seriesFolding Cheat Sheet #3 - third in a series
Folding Cheat Sheet #3 - third in a series
 
Folding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a seriesFolding Cheat Sheet #2 - second in a series
Folding Cheat Sheet #2 - second in a series
 
Folding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a seriesFolding Cheat Sheet #1 - first in a series
Folding Cheat Sheet #1 - first in a series
 
Scala Left Fold Parallelisation - Three Approaches
Scala Left Fold Parallelisation- Three ApproachesScala Left Fold Parallelisation- Three Approaches
Scala Left Fold Parallelisation - Three Approaches
 
Tagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also ProgramsTagless Final Encoding - Algebras and Interpreters and also Programs
Tagless Final Encoding - Algebras and Interpreters and also Programs
 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with Views
 
A sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in ScalaA sighting of traverse_ function in Practical FP in Scala
A sighting of traverse_ function in Practical FP in Scala
 
A sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in ScalaA sighting of traverseFilter and foldMap in Practical FP in Scala
A sighting of traverseFilter and foldMap in Practical FP in Scala
 
A sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in ScalaA sighting of sequence function in Practical FP in Scala
A sighting of sequence function in Practical FP in Scala
 
N-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets CatsN-Queens Combinatorial Puzzle meets Cats
N-Queens Combinatorial Puzzle meets Cats
 
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
Kleisli composition, flatMap, join, map, unit - implementation and interrelat...
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
 
Jordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axiomsJordan Peterson - The pursuit of meaning and related ethical axioms
Jordan Peterson - The pursuit of meaning and related ethical axioms
 

Recently uploaded

The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)Roberto Bettazzoni
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletAndrea Goulet
 
Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024Henry Schreiner
 
architecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdfarchitecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdfWSO2
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfICS
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Eraconfluent
 
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Andrea Goulet
 
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...drm1699
 
From Knowledge Graphs via Lego Bricks to scientific conversations.pptx
From Knowledge Graphs via Lego Bricks to scientific conversations.pptxFrom Knowledge Graphs via Lego Bricks to scientific conversations.pptx
From Knowledge Graphs via Lego Bricks to scientific conversations.pptxNeo4j
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdfSelfMade bd
 
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...Abortion Clinic
 
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024MulesoftMunichMeetup
 
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAOpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAShane Coughlan
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AIAGATSoftware
 
Weeding your micro service landscape.pdf
Weeding your micro service landscape.pdfWeeding your micro service landscape.pdf
Weeding your micro service landscape.pdftimtebeek1
 
Food Delivery Business App Development Guide 2024
Food Delivery Business App Development Guide 2024Food Delivery Business App Development Guide 2024
Food Delivery Business App Development Guide 2024Chirag Panchal
 
From Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIFrom Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIInflectra
 

Recently uploaded (20)

Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
 
The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea Goulet
 
Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024
 
Abortion Pill Prices Turfloop ](+27832195400*)[ 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Turfloop ](+27832195400*)[ 🏥 Women's Abortion Clinic in ...Abortion Pill Prices Turfloop ](+27832195400*)[ 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Turfloop ](+27832195400*)[ 🏥 Women's Abortion Clinic in ...
 
architecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdfarchitecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdf
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdf
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Era
 
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
 
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
 
From Knowledge Graphs via Lego Bricks to scientific conversations.pptx
From Knowledge Graphs via Lego Bricks to scientific conversations.pptxFrom Knowledge Graphs via Lego Bricks to scientific conversations.pptx
From Knowledge Graphs via Lego Bricks to scientific conversations.pptx
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
 
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
Abortion Pill Prices Jane Furse ](+27832195400*)[ 🏥 Women's Abortion Clinic i...
 
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
 
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAOpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AI
 
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
 
Weeding your micro service landscape.pdf
Weeding your micro service landscape.pdfWeeding your micro service landscape.pdf
Weeding your micro service landscape.pdf
 
Food Delivery Business App Development Guide 2024
Food Delivery Business App Development Guide 2024Food Delivery Business App Development Guide 2024
Food Delivery Business App Development Guide 2024
 
From Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIFrom Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST API
 

Computer Graphics in Java and Scala - Part 1b

  • 1. Computer Graphics in Java and Scala Part 1b first see the Scala program translated into Java then see the Scala program modified to produce a more intricate drawing @philip_schwarz slides by https://www.slideshare.net/pjschwarz
  • 2. In this slide deck, which is an addendum to Part 1, we are going to do the following: • Translate the Scala program from Part 1 into Java • Modify the Scala program so that rather than drawing 50 concentric triangles, it draws a chessboard-like grid in which each cell consists of 10 concentric squares. • Eliminate an unsatisfactory feature of the above drawing by changing the angle by which squares are twisted, plus improve the drawing by increasing the number of squares drawn.
  • 3. case class Point(x: Float, y: Float) object Triangle: def apply(centre:Point,side:Float,height:Float): Triangle = val Point(x,y) = centre val halfSide = 0.5F * side val bottomLeft = Point(x - halfSide, y - 0.5F * height) val bottomRight = Point(x + halfSide, y - 0.5F * height) val top = Point(x, y + 0.5F * height ) Triangle(bottomLeft,bottomRight,top) case class Triangle(a: Point, b: Point, c: Point) public record Triangle(Point a, Point b, Point c) { static Triangle instance(Point centre,Float side,Float height) { float x = centre.x(), y = centre.y(); var halfSide = 0.5F * side; var bottomLeft = new Point(x - halfSide, y - 0.5F * height); var bottomRight = new Point(x + halfSide, y - 0.5F * height); var top = new Point(x, y + 0.5F * height); return new Triangle(bottomLeft,bottomRight,top); } } public record Point(Float x, Float y) { } Let’s start translating the Scala program into Java. @philip_schwarz
  • 5. class TrianglesPanel extends JPanel: setBackground(Color.white) override def paintComponent(g: Graphics): Unit = super.paintComponent(g) val panelSize: Dimension = getSize() val panelWidth = panelSize.width - 1 val panelHeight = panelSize.height - 1 val panelCentre = Point(panelWidth / 2, panelHeight / 2) val triangleSide = 0.95F * Math.min(panelWidth, panelHeight) val triangleHeight = (0.5F * triangleSide) * Math.sqrt(3).toFloat …<shrinkAndTwist, draw and drawLine functions>… val triangle = Triangle(panelCentre, triangleSide, triangleHeight) LazyList .iterate(triangle)(shrinkAndTwist) .take(50) .foreach(draw) public class TrianglesPanel extends JPanel { public TrianglesPanel() { setBackground(Color.white); } public void paintComponent(Graphics g){ super.paintComponent(g); Dimension panelSize = getSize(); int panelWidth = panelSize.width - 1; int panelHeight = panelSize.height - 1; var panelCentre = new Point(panelWidth / 2F, panelHeight / 2F); var triangleSide = 0.95F * Math.min(panelWidth, panelHeight); var triangleHeight = (0.5F * triangleSide) * (float)Math.sqrt(3); var triangle = Triangle.instance(panelCentre, triangleSide, triangleHeight); Stream .iterate(triangle, this::shrinkAndTwist) .limit(50) .forEach(t -> draw(g, t, panelHeight)); } …<shrinkAndTwist, draw and drawLine functions>… }
  • 6. val shrinkAndTwist: Triangle => Triangle = val q = 0.05F val p = 1 - q def combine(a: Point, b: Point) = Point(p * a.x + q * b.x, p * a.y + q * b.y) { case Triangle(a,b,c) => Triangle(combine(a,b), combine(b,c), combine(c,a)) } Triangle shrinkAndTwist(Triangle t) { return new Triangle( combine(t.a(), t.b()), combine(t.b(), t.c()), combine(t.c(), t.a()) ); } Point combine(Point a, Point b) { var q = 0.05F; var p = 1 - q; return new Point(p * a.x() + q * b.x(), p * a.y() + q * b.y()); } val draw: Triangle => Unit = case Triangle(a, b, c) => drawLine(a, b) drawLine(b, c) drawLine(c, a) def drawLine(a: Point, b: Point): Unit = val (ax,ay) = a.deviceCoords(panelHeight) val (bx,by) = b.deviceCoords(panelHeight) g.drawLine(ax, ay, bx, by) void draw(Graphics g, Triangle t, int panelHeight) { drawLine(g, t.a(), t.b(), panelHeight); drawLine(g, t.b(), t.c(), panelHeight); drawLine(g, t.c(), t.a(), panelHeight); } void drawLine(Graphics g, Point a, Point b, int panelHeight) { var aCoords = deviceCoords(a, panelHeight); var bCoords = deviceCoords(b, panelHeight); int ax = aCoords.x, ay = aCoords.y, bx = bCoords.x, by = bCoords.y; g.drawLine(ax, ay, bx, by); } java.awt.Point deviceCoords(Point p, int panelHeight) { return new java.awt.Point(Math.round(p.x()), panelHeight - Math.round(p.y())); } extension (p: Point) def deviceCoords(panelHeight: Int): (Int, Int) = (Math.round(p.x), panelHeight - Math.round(p.y))
  • 7. class Triangles: JFrame.setDefaultLookAndFeelDecorated(true) val frame = new JFrame("Triangles: 50 triangles inside each other") frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE) frame.setSize(600, 400) frame.add(TrianglesPanel()) frame.setVisible(true) @main def main: Unit = // Create a frame/panel on the event dispatching thread SwingUtilities.invokeLater( new Runnable(): def run: Unit = Triangles() ) public class Triangles { public static void main(String[] args) { // Create a frame/panel on the event dispatching thread SwingUtilities.invokeLater( () -> new Triangles().drawTriangles() ); } void drawTriangles() { JFrame.setDefaultLookAndFeelDecorated(true); var frame = new JFrame("Triangles: 50 triangles inside each other"); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setSize(600, 400); frame.add(new TrianglesPanel()); frame.setVisible(true); } }
  • 8. On the next slide we check that the Java program works as intended.
  • 9.
  • 10. Now we turn to an exercise that sees us modify the Scala program so that rather than drawing 50 concentric triangles, it draws a chessboard-like grid in which each cell consists of 10 concentric squares.
  • 11. Exercises … 1.2 Replace the triangles of program Triangles.java with squares and draw a great many of them, arranged in a chessboard, as show in Fig 1.11. As usual, this chessboard, consists of 𝑛 × 𝑛 normal squares (with horizontal and vertical edges), where 𝑛 = 8. Each of these actually consists of 𝑘 squares of different sizes, with 𝑘 = 10. Finally, the value 𝑞 = 0.2 (and 𝑝 = 1 − 𝑞 = 0.8) was used to divide each edge into two parts with ratio 𝑝 ∶ 𝑞 (see also program Triangles.java of section 1.2), but the interesting pattern of Fig 1.11 was obtained by reversing the roles of 𝑝 and 𝑞 in half of the 𝑛 × 𝑛 ‘normal’ squares, which is similar to the black and white squares of a normal chessboard. Your program should accept the values 𝑛, 𝑘 and 𝑞 as program arguments. Figure 1.11 A chessboard of squares
  • 12. On the next slide we start modifying the Scala program so that it meets the new requirements (though we are not going to bother getting the program to accept 𝑛, 𝑘 and 𝑞 as parameters). @philip_schwarz
  • 13. object Triangle: def apply(centre: Point, side: Float, height: Float): Triangle = val Point(x,y) = centre val halfSide = 0.5F * side val bottomLeft = Point(x - halfSide, y - 0.5F * height) val bottomRight = Point(x + halfSide, y - 0.5F * height) val top = Point(x, y + 0.5F * height ) Triangle(bottomLeft,bottomRight,top) case class Triangle(a: Point, b: Point, c: Point) case class Square(a: Point, b: Point, c: Point, d: Point) object Square: def apply(centre: Point, side: Float): Square = val Point(x,y) = centre val halfSide = 0.5F * side val bottomLeft = Point(x - halfSide, y - halfSide) val bottomRight = Point(x + halfSide, y - halfSide) val topRight = Point(x + halfSide, y + halfSide) val topLeft = Point(x - halfSide, y + halfSide) Square(bottomLeft,bottomRight,topRight,topLeft)
  • 14. LazyList .iterate(triangle)(shrinkAndTwist) .take(50) .foreach(draw) for (row, startDirection) <- (0 until gridSize) zip alternatingDirections(Direction.Right) (col, twistDirection) <- (0 until gridSize) zip alternatingDirections(startDirection) square = Square(squareCentre(row,col),squareSide) yield LazyList .iterate(square)(shrinkAndTwist(twistDirection)) .take(10) .foreach(draw) def squareCentre(row: Int, col: Int): Point = Point(panelCentre.x-(gridSize/2*squareSide)+(col*squareSide)+squareSide/2, panelCentre.y-(gridSize/2*squareSide)+(row*squareSide)+squareSide/2) enum Direction: case Left, Right def reversed: Direction = if this == Right then Left else Right def alternatingDirections(startDirection: Direction): LazyList[Direction] = LazyList.iterate(startDirection)(_.reversed) We are going to use a for comprehension to work through each of the 64 cells in the 8 × 8 grid, ensuring that each time we move from one cell to the next, we invert the direction (right = clockwise and left = counterclockwise) in which we twist the concentric squares drawn within a cell.
  • 15. object TrianglesPanel extends JPanel: setBackground(Color.white) override def paintComponent(g: Graphics): Unit = super.paintComponent(g) val panelSize: Dimension = getSize() val panelWidth = panelSize.width - 1 val panelHeight = panelSize.height - 1 val panelCentre = Point(panelWidth / 2, panelHeight / 2) val triangleSide = 0.95F * Math.min(panelWidth, panelHeight) val triangleHeight = (0.5F * triangleSide) * Math.sqrt(3).toFloat …<shrinkAndTwist, draw and drawLine functions>… val triangle = Triangle(panelCentre, triangleSide, triangleHeight) LazyList .iterate(triangle)(shrinkAndTwist) .take(50) .foreach(draw) object SquaresPanel extends JPanel: setBackground(Color.white) override def paintComponent(g: Graphics): Unit = super.paintComponent(g) val panelSize: Dimension = getSize() val panelWidth = panelSize.width - 1 val panelHeight = panelSize.height - 1 val panelCentre = Point(panelWidth / 2, panelHeight / 2) val gridSize = 8 val squareSide: Float = 0.95F * Math.min(panelWidth, panelHeight) / gridSize …<shrinkAndTwist, draw and drawLine functions>… def squareCentre(row: Int, col: Int): Point = Point(panelCentre.x-(gridSize/2*squareSide)+(col*squareSide)+squareSide/2, panelCentre.y-(gridSize/2*squareSide)+(row*squareSide)+squareSide/2) for (row, startDirection) <- (0 until gridSize) zip alternatingDirections(Direction.Right) (col, twistDirection) <- (0 until gridSize) zip alternatingDirections(startDirection) square = Square(squareCentre(row,col),squareSide) yield LazyList .iterate(square)(shrinkAndTwist(twistDirection)) .take(10) .foreach(draw)
  • 16. val shrinkAndTwist: Triangle => Triangle = val q = 0.05F val p = 1 - q def combine(a: Point, b: Point) = Point(p * a.x + q * b.x, p * a.y + q * b.y) { case Triangle(a,b,c) => Triangle( combine(a,b), combine(b,c), combine(c,a)) } val draw: Triangle => Unit = case Triangle(a, b, c) => drawLine(a, b) drawLine(b, c) drawLine(c, a) def drawLine(a: Point, b: Point): Unit = val (ax,ay) = a.deviceCoords(panelHeight) val (bx,by) = b.deviceCoords(panelHeight) g.drawLine(ax, ay, bx, by) def shrinkAndTwist(direction: Direction): Square => Square = val q = if direction == Direction.Right then 0.2F else 0.8F val p = 1 - q def combine(a: Point, b: Point) = Point(p * a.x + q * b.x, p * a.y + q * b.y) { case Square(a,b,c,d) => Square( combine(a,b), combine(b,c), combine(c,d), combine(d,a)) } def drawLine(a: Point, b: Point): Unit = val (ax,ay) = a.deviceCoords(panelHeight) val (bx,by) = b.deviceCoords(panelHeight) g.drawLine(ax, ay, bx, by) val draw: Square => Unit = case Square(a, b, c, d) => drawLine(a, b) drawLine(b, c) drawLine(c, d) drawLine(d, a)
  • 17. def drawTriangles: Unit = JFrame.setDefaultLookAndFeelDecorated(true) val frame = new JFrame("Triangles: 50 triangles inside each other") frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE) frame.setSize(600, 400) frame.add(TrianglesPanel) frame.setVisible(true) @main def trianglesMain: Unit = // Create the frame/panel on the event dispatching thread SwingUtilities.invokeLater( new Runnable(): def run: Unit = drawTriangles ) def drawSquares: Unit = JFrame.setDefaultLookAndFeelDecorated(true) val frame = new JFrame("A chessboard of squares") frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE) frame.setSize(600, 400) frame.add(SquaresPanel) frame.setVisible(true) @main def squaresMain: Unit = // Create the frame/panel on the event dispatching thread SwingUtilities.invokeLater( new Runnable(): def run: Unit = drawSquares )
  • 18. On the next slide we have a go at running the modified Scala program.
  • 19.
  • 20. That’s nice, but it turns out that there is an unsatisfactory feature in that drawing: we can improve the drawing by removing that feature and increasing the number of squares drawn. @philip_schwarz
  • 21. This idea is further illustrated by drawing the pattern shown in figure 3.3a. At first sight it looks complicated, but on closer inspection it is seen to be simply a square, outside a square, outside a square etc. The squares are getting successively smaller and they are rotating through a constant angle. In order to draw the diagram, a technique is needed which, when given a general square, draws a smaller internal square rotated through this fixed angle. Suppose the general square has corners {(xi , yi) | i = 1, 2, 3, 4} and the i th side of the square is the line joining (xi , yi) to (xi+1 , yi+1) - assuming additions of subscripts are modulo 4 - that is, 4 + 1 ≡ 1. A general point on this side of the square, (x’i , y’i), is given by ((1 - 𝜇) × xi + 𝜇 × xi+1, (1 - 𝜇) × yi + 𝜇 × yi+1) where 0 ≤ 𝜇 ≤ 1
  • 22. In fact 𝜇 : 1 - 𝜇 is the ratio in which the side is cut by this point. If 𝜇 is fixed and the four points {(xi , yi) | i = 1, 2, 3, 4} are calculated in the above manner, then the sides of the new square make an angle 𝛼 = tan-1[𝜇/(1 -𝜇)] with the corresponding side of the outer square. So by keeping 𝜇 fixed for each new square, the angle between consecutive squares remains constant at 𝛼. In figure 3.3a … there are 21 squares and 𝜇 = 0.1. There is an unsatisfactory feature of the pattern in figure 3.3a: the inside of the pattern is 'untidy', the sides of the innermost square being neither parallel to nor at 𝜋/4 radians to the corresponding side of the outermost square. This is corrected simply by changing the value of 𝜇 so as to produce the required relationship between the innermost and outermost squares. As was previously noted, with the calculation of each new inner square, the corresponding sides are rotated through an angle of tan−1[𝜇/(1 −𝜇)] radians. After 𝑛 + 1 squares are drawn, the inner square is rotated by 𝑛 × tan−1[𝜇/(1 −𝜇)] radians relative to the outer square. For a satisfactory diagram this angle must be an integer multiple of 𝜋/4. That is, 𝑛 × tan−1[𝜇/(1 −𝜇)] = t(𝜋/4) for some integer t, and hence 𝜇 = tan[t(𝜋/4n)] tan[t(𝜋/4n)]+1 To produce figure 3.3b, 𝑛 = 20 and t = 3 are chosen.
  • 23. val mu: Float = val t = 3 val x = Math.tan(t * (Math.PI/(4 * squareCount))) (x / (x + 1)).toFloat def shrinkAndTwist(direction: Direction): Square => Square = val q = if direction == Direction.Right then 0.2F else 0.8F val p = 1 - q def combine(a: Point, b: Point) = Point(p * a.x + q * b.x, p * a.y + q * b.y) { case Square(a,b,c,d) => Square( combine(a,b), combine(b,c), combine(c,d), combine(d,a)) } def shrinkAndTwist(direction: Direction): Square => Square = val q = if direction == Direction.Right then mu else 1 - mu val p = 1 - q def combine(a: Point, b: Point) = Point(p * a.x + q * b.x, p * a.y + q * b.y) { case Square(a,b,c,d) => Square( combine(a,b), combine(b,c), combine(c,d), combine(d,a)) } val squareCount = 20 LazyList .iterate(square)(shrinkAndTwist(twistDirection)) .take(10) .foreach(draw) LazyList .iterate(square)(shrinkAndTwist(twistDirection)) .take(squareCount + 1) .foreach(draw)
  • 24. Let’ run the improved Scala program.
  • 25.
  • 26.
  • 27. Before and after the improvements
  • 28. That’s all. I hope you enjoyed that. @philip_schwarz