Difference between revisions of "Render Part A Assignment"

From CSE425S Wiki
Jump to navigation Jump to search
 
(19 intermediate revisions by the same user not shown)
Line 1: Line 1:
=OpenGL=
+
=Diagram=
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBegin.xml glBegin]
+
[[File:Diagram_part_a.png|600px]]
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glVertex.xml glVertex2f]
 
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glEnd.xml glEnd]
 
  
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glColor.xml glColor3f]
+
=Code to Use=
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glEnable.xml glEnable]
+
==[https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse425s/current/doc/Graphics.html Graphics]==
 +
: [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse425s/current/doc/Graphics.html#draw_convex_polygon-instance_method draw_convex_polygon]
 +
: [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse425s/current/doc/Graphics.html#draw_curve-instance_method draw_curve]
 +
: [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse425s/current/doc/Graphics.html#draw_image-instance_method draw_image]
 +
: [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse425s/current/doc/Graphics.html#draw_string-instance_method draw_string]
  
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glPushMatrix.xml glPushMatrix]
+
==Point2==
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glTranslate.xml glTranslatef]
 
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glRotate.xml glRotatef]
 
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glPopMatrix.xml glPopMatrix]
 
 
 
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glMap1.xml glMap1f]
 
 
 
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glRasterPos.xml glRasterPos2f]
 
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glPixelZoom.xml glPixelZoom]
 
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glDrawPixels.xml glDrawPixels]
 
 
 
: [https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glClearColor.xml glClearColor]
 
  
=GLUT=
+
==[https://ruby-doc.org/core-2.6/Math.html Math]==
: [https://www.opengl.org/resources/libraries/glut/spec3/node76.html glutBitmapCharacter]
+
: [https://ruby-doc.org/core-2.6/Math.html#method-c-cos Math.cos(radians)]
 +
: [https://ruby-doc.org/core-2.6/Math.html#method-c-sin Math.sin(radians)]
  
 +
<!--
 
=Code to Investigate=
 
=Code to Investigate=
 
==Cavalcade of Graphics==
 
==Cavalcade of Graphics==
{{RubyToRun|cavalcade_of_graphics|render/examples|main}}
+
{{RubyToRun|cavalcade_of_graphics|cavalcade_of_graphics|main}}
  
 
[[File:Cavalcade of graphics.png]]
 
[[File:Cavalcade of graphics.png]]
 +
-->
  
 
=Code to Implement=
 
=Code to Implement=
Each of the renderable components has its own file in the <code>src/main/ruby/render/assignment</code> directory.
+
Each of the renderable components has its own file in the <code>src/main/ruby/drawings/core</code> directory.
  
 
Be sure to add accessors for all constructor parameters.
 
Be sure to add accessors for all constructor parameters.
Line 37: Line 31:
  
 
==Equilateral Triangle==
 
==Equilateral Triangle==
{{RubyToImplement|equilateral_triangle|render/assignment|EquilateralTriangle|Object|initialize(half_side_length)<br/>half_side_length()<br>half_side_length&#61;()<br/>render()}}
+
{{RubyToImplement|equilateral_triangle|drawings/core|EquilateralTriangle|Object|initialize(half_side_length)<br/>half_side_length()<br>half_side_length&#61;()<br/>render(g)}}
  
 
[[File:Equilateral Triangle Render Studio.svg]]
 
[[File:Equilateral Triangle Render Studio.svg]]
Line 57: Line 51:
 
So, the bottom left point A's x coordinate should be <code>-half_side_length</code> and its y coordinate should be <code>-1/3 height</code>.
 
So, the bottom left point A's x coordinate should be <code>-half_side_length</code> and its y coordinate should be <code>-1/3 height</code>.
  
{{RubyToRun|equilateral_triangle|render/assignment|main}}
+
{{RubyToRun|equilateral_triangle|drawings/core|main}}
  
 
[[File:Render_equilateral_triangle.png]]
 
[[File:Render_equilateral_triangle.png]]
  
 
==Rectangle==
 
==Rectangle==
{{RubyToImplement|rectangle|render/assignment|Rectangle|Object|initialize(half_width, half_height)<br/>half_width()<br>half_width&#61;()<br/>half_height()<br>half_height&#61;()<br/>render()}}
+
{{RubyToImplement|rectangle|drawings/core|Rectangle|Object|initialize(half_width, half_height)<br/>half_width()<br>half_width&#61;()<br/>half_height()<br>half_height&#61;()<br/>render(g)}}
  
 
Add an [https://www.rubyguides.com/2018/11/attr_accessor/ accessors] for half_width and half_height.
 
Add an [https://www.rubyguides.com/2018/11/attr_accessor/ accessors] for half_width and half_height.
  
{{RubyToRun|rectangle|render/assignment|main}}
+
{{RubyToRun|rectangle|drawings/core|main}}
  
 
[[File:Render_rectangle.png]]
 
[[File:Render_rectangle.png]]
  
 
==Ellipse==
 
==Ellipse==
{{RubyToImplement|ellipse|render/assignment|Ellipse|Object|initialize(x_radius, y_radius)<br/>x_radius()<br>x_radius&#61;()<br/>y_radius()<br>y_radius&#61;()<br/>render()}}
+
{{RubyToImplement|ellipse|drawings/core|Ellipse|Object|initialize(x_radius, y_radius)<br/>x_radius()<br>x_radius&#61;()<br/>y_radius()<br>y_radius&#61;()<br/>render(g)}}
  
 
Add an [https://www.rubyguides.com/2018/11/attr_accessor/ accessors] for x_radius and y_radius.
 
Add an [https://www.rubyguides.com/2018/11/attr_accessor/ accessors] for x_radius and y_radius.
Line 80: Line 74:
 
     delta_theta = (2*Math::PI) /slice_count</nowiki>
 
     delta_theta = (2*Math::PI) /slice_count</nowiki>
  
{{RubyToRun|ellipse|render/assignment|main}}
+
{{RubyToRun|ellipse|drawings/core|main}}
  
 
[[File:Render_ellipse.png]]
 
[[File:Render_ellipse.png]]
  
 
==CircularSegment==
 
==CircularSegment==
{{RubyToImplement|circular_segment|render/assignment|CircularSegment|Object|initialize(x_radius, y_radius, theta_a, theta_z)<br/>render()}}
+
{{RubyToImplement|circular_segment|drawings/core|CircularSegment|Object|initialize(x_radius, y_radius, theta_a, theta_z)<br/>render(g)}}
  
 
In geometry a [https://en.wikipedia.org/wiki/Chord_(geometry) chord] is a line segment which joins two points on a curve.  We will define a <code>class CircularSegment</code> which renders a filled shape of an ellipse cut at the chord between theta_a and theta_z.
 
In geometry a [https://en.wikipedia.org/wiki/Chord_(geometry) chord] is a line segment which joins two points on a curve.  We will define a <code>class CircularSegment</code> which renders a filled shape of an ellipse cut at the chord between theta_a and theta_z.
Line 98: Line 92:
 
Note: a Chord with 32 slices will have 33 points.
 
Note: a Chord with 32 slices will have 33 points.
  
{{RubyToRun|circular_segment|render/assignment|main}}
+
{{RubyToRun|circular_segment|drawings/core|main}}
  
 
[[File:Render_chord.png]]
 
[[File:Render_chord.png]]
  
 
==Image==
 
==Image==
{{RubyToImplement|image|render/assignment|Image|Object|initialize(path)<br/>render()}}
+
{{RubyToImplement|image|drawings/core|Image|Object|initialize(path)<br/>render(g)}}
  
 
should draw the pixels from (0,0)
 
should draw the pixels from (0,0)
  
{{RubyToRun|image|render/assignment|main}}
+
{{RubyToRun|image|drawings/core|main}}
  
 
[[File:Render_image.png]]
 
[[File:Render_image.png]]
  
 
==Text==
 
==Text==
{{RubyToImplement|image|render/assignment|Text|Object|initialize(text, font)<br/>render()}}
+
{{RubyToImplement|text|drawings/core|Text|Object|initialize(text, font)<br/>render(g)}}
  
{{RubyToRun|text|render/assignment|main}}
+
{{RubyToRun|text|drawings/core|main}}
  
 
[[File:Render_text.png]]
 
[[File:Render_text.png]]
 
==Point2==
 
To support Bézier curves you will want to implement Point2 in point2.rb.  You may wish to use Ruby's convenient [https://ruby-doc.org/core-2.4.2/Struct.html Struct] construct.
 
 
You should be able to construct a Point2 with an x and a y and be able to access those values.
 
  
 
==Bézier Curve==
 
==Bézier Curve==
{{RubyToImplement|bezier_curve|render/assignment|BezierCurve|Object|initialize(control_points)<br/>render()}}
+
{{RubyToImplement|bezier_curve|drawings/core|BezierCurve|Object|initialize(control_points)<br/>render(g)}}
  
NOTE: you need not implement the interpolation yourself.  Check cavalcade_of_graphics for an example of how to draw a curve.
+
NOTE: you need not implement the interpolation yourself.  Use the [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse425s/current/doc/Graphics.html#draw_curve-instance_method draw_curve] method on [https://www.cse.wustl.edu/~dennis.cosgrove/courses/cse425s/current/doc/Graphics.html Graphics].
  
 
{| class="wikitable" style="text-align: right; "
 
{| class="wikitable" style="text-align: right; "
Line 142: Line 131:
 
|}
 
|}
  
{{RubyToRun|bezier_curve|render/assignment|main}}
+
{{RubyToRun|bezier_curve|drawings/core|main}}
  
 
[[File:Render_bezier_curve.png]]
 
[[File:Render_bezier_curve.png]]
  
 
=Testing Your Solution=
 
=Testing Your Solution=
 +
==Unit Test==
 +
{{RubyUnitTest|*|drawings/core/relatively_fast/part_a}}
 +
 +
{{RubyUnitTest|*|drawings/core/relatively_slow/part_a}}
 +
 
==Visual Comparison==
 
==Visual Comparison==
{{RubyToRun|part_a_test_snapshots_web_page_generator|render/part_a|test}}
+
{{RubyToRun|part_a_snapshots_web_page_generator|drawings/core/snapshots|test}}
  
==Unit Test==
+
==Somewhat Outdated Testing Demo==
{{RubyUnitTest|part_a_unit_test|render/part_a}}
+
<youtube>utK0TewIRjc</youtube>

Latest revision as of 11:24, 9 August 2023

Diagram

Diagram part a.png

Code to Use

Graphics

draw_convex_polygon
draw_curve
draw_image
draw_string

Point2

Math

Math.cos(radians)
Math.sin(radians)


Code to Implement

Each of the renderable components has its own file in the src/main/ruby/drawings/core directory.

Be sure to add accessors for all constructor parameters.

How to use attr_accessor

Equilateral Triangle

file: src/main/ruby/drawings/core/equilateral_triangle.rb Ruby logo.svg
class: EquilateralTriangle
superclass: Object
methods: initialize(half_side_length)
half_side_length()
half_side_length=()
render(g)

Equilateral Triangle Render Studio.svg

wikipedia

WARNING: Ruby division of two integers results in an integer. For example: 1/3 == 0

The triangle should be equilateral, rendered with its the origin at the center of mass.

Your constructor should accept a half_side_length parameter.

Add an accessor for half_side_length.

The height of the triangle should be side_length * sqrt(3)/2

The center of mass is one third from the bottom.

So, the bottom left point A's x coordinate should be -half_side_length and its y coordinate should be -1/3 height.

file to run: src/main/ruby/drawings/core/equilateral_triangle.rb Ruby logo.svg

Render equilateral triangle.png

Rectangle

file: src/main/ruby/drawings/core/rectangle.rb Ruby logo.svg
class: Rectangle
superclass: Object
methods: initialize(half_width, half_height)
half_width()
half_width=()
half_height()
half_height=()
render(g)

Add an accessors for half_width and half_height.

file to run: src/main/ruby/drawings/core/rectangle.rb Ruby logo.svg

Render rectangle.png

Ellipse

file: src/main/ruby/drawings/core/ellipse.rb Ruby logo.svg
class: Ellipse
superclass: Object
methods: initialize(x_radius, y_radius)
x_radius()
x_radius=()
y_radius()
y_radius=()
render(g)

Add an accessors for x_radius and y_radius.

Note: to produce the reference image the code below was used:

    slice_count = 32
    delta_theta = (2*Math::PI) /slice_count
file to run: src/main/ruby/drawings/core/ellipse.rb Ruby logo.svg

Render ellipse.png

CircularSegment

file: src/main/ruby/drawings/core/circular_segment.rb Ruby logo.svg
class: CircularSegment
superclass: Object
methods: initialize(x_radius, y_radius, theta_a, theta_z)
render(g)

In geometry a chord is a line segment which joins two points on a curve. We will define a class CircularSegment which renders a filled shape of an ellipse cut at the chord between theta_a and theta_z.

Chord theta a z.png

Note: to produce the reference image the code below was used:

    slice_count = 32
    delta_theta = (@theta_z-@theta_a) / slice_count

Note: a Chord with 32 slices will have 33 points.

file to run: src/main/ruby/drawings/core/circular_segment.rb Ruby logo.svg

Render chord.png

Image

file: src/main/ruby/drawings/core/image.rb Ruby logo.svg
class: Image
superclass: Object
methods: initialize(path)
render(g)

should draw the pixels from (0,0)

file to run: src/main/ruby/drawings/core/image.rb Ruby logo.svg

Render image.png

Text

file: src/main/ruby/drawings/core/text.rb Ruby logo.svg
class: Text
superclass: Object
methods: initialize(text, font)
render(g)
file to run: src/main/ruby/drawings/core/text.rb Ruby logo.svg

Render text.png

Bézier Curve

file: src/main/ruby/drawings/core/bezier_curve.rb Ruby logo.svg
class: BezierCurve
superclass: Object
methods: initialize(control_points)
render(g)

NOTE: you need not implement the interpolation yourself. Use the draw_curve method on Graphics.

Quadratic (Second Order) Curve: Bézier 2 big.svg Bézier 2 big.gif
Quadratic (Third Order) Curve: Bézier 3 big.svg Bézier 3 big.gif
Fourth Order Curve: Bézier 4 big.svg Bézier 4 big.gif
file to run: src/main/ruby/drawings/core/bezier_curve.rb Ruby logo.svg

Render bezier curve.png

Testing Your Solution

Unit Test

file: src/test/ruby/drawings/core/relatively_fast/part_a/*.rb Ruby logo.svg UnitTest

note: ensure that you have removed all printing to receive credit for any assignment.

file: src/test/ruby/drawings/core/relatively_slow/part_a/*.rb Ruby logo.svg UnitTest

note: ensure that you have removed all printing to receive credit for any assignment.

Visual Comparison

file to run: src/test/ruby/drawings/core/snapshots/part_a_snapshots_web_page_generator.rb Ruby logo.svg

Somewhat Outdated Testing Demo