Class: HexaPDF::Content::GraphicObject::EndpointArc

Inherits:
Object
  • Object
show all
Includes:
Utils, Utils::MathHelpers
Defined in:
lib/hexapdf/content/graphic_object/endpoint_arc.rb

Overview

This class describes an elliptical arc in endpoint parameterization. It allows one to generate an arc from the current point to a given point, similar to Canvas#line_to. Behind the scenes the endpoint parameterization is turned into a center parameterization and drawn with Arc.

Note that only the path of the arc itself is added to the canvas. So depending on the use-case the path itself still has to be, for example, stroked.

This graphic object is registered under the :endpoint_arc key for use with the HexaPDF::Content::Canvas class.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 10)
canvas.move_to(0, 0).draw(arc).stroke

See: Arc, ARC - https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes (in the version of about 2016, see https://web.archive.org/web/20160310153722/https://www.w3.org/TR/SVG/implnote.html).

Constant Summary

Constants included from Utils

Utils::EPSILON

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils::MathHelpers

deg_to_rad, rad_to_deg

Constructor Details

#initializeEndpointArc

Creates an endpoint arc with default values x=0, y=0, a=0, b=0, inclination=0, large_arc=true, clockwise=false (a line to the origin).

Examples:

#>pdf-center
canvas.move_to(30, 30).draw(:endpoint_arc).stroke


171
172
173
174
175
176
177
178
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 171

def initialize
  @x = @y = 0
  @a = @b = 0
  @inclination = 0
  @large_arc = true
  @clockwise = false
  @max_curves = nil
end

Instance Attribute Details

#aObject (readonly)

Length of semi-major axis, defaults to 0.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
canvas.move_to(0, 0).draw(arc).stroke
canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, a: 40).stroke


103
104
105
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 103

def a
  @a
end

#bObject (readonly)

Length of semi-minor axis, defaults to 0.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
canvas.move_to(0, 0).draw(arc).stroke
canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, b: 50).stroke


113
114
115
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 113

def b
  @b
end

#clockwiseObject (readonly)

Direction of arc - if true in clockwise direction, else in counterclockwise direction (the default).

This is needed, for example, when filling paths using the nonzero winding number rule to achieve different effects.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
canvas.move_to(0, 0).draw(arc).stroke
canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, clockwise: true).stroke


149
150
151
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 149

def clockwise
  @clockwise
end

#inclinationObject (readonly)

Inclination in degrees of semi-major axis in respect to x-axis, defaults to 0.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
canvas.move_to(0, 0).draw(arc).stroke
canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, inclination: 45).stroke


123
124
125
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 123

def inclination
  @inclination
end

#large_arcObject (readonly)

Large arc choice - if true (the default) use the large arc (i.e. the one spanning more than 180 degrees), else the small arc

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
canvas.move_to(0, 0).draw(arc).stroke
canvas.stroke_color("hp-blue").
move_to(0, 0).draw(arc, large_arc: false, clockwise: true).stroke


135
136
137
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 135

def large_arc
  @large_arc
end

#max_curvesObject

The maximal number of curves used for approximating a complete ellipse.

See Arc#max_curves for details.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
canvas.move_to(0, 0).draw(arc, max_curves: 1).stroke
canvas.stroke_color("hp-blue").
move_to(0, 0).draw(arc, max_curves: 2).stroke


162
163
164
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 162

def max_curves
  @max_curves
end

#xObject (readonly)

x-coordinate of endpoint, defaults to 0.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
canvas.move_to(0, 0).draw(arc).stroke
canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, x: -50).stroke


83
84
85
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 83

def x
  @x
end

#yObject (readonly)

y-coordinate of endpoint, defaults to 0.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
canvas.move_to(0, 0).draw(arc).stroke
canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, y: -20).stroke


93
94
95
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 93

def y
  @y
end

Class Method Details

.configure(**kwargs) ⇒ Object

Creates and configures a new endpoint arc object.

See #configure for the allowed keyword arguments.



71
72
73
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 71

def self.configure(**kwargs)
  new.configure(**kwargs)
end

Instance Method Details

#configure(x: nil, y: nil, a: nil, b: nil, inclination: nil, large_arc: nil, clockwise: nil, max_curves: nil) ⇒ Object

Configures the endpoint arc with

  • endpoint (+x+, y),
  • semi-major axis a,
  • semi-minor axis b,
  • an inclination in respect to the x-axis of inclination degrees,
  • the given large_arc flag,
  • the given clockwise flag and.
  • the given maximum number of approximation curves.

The large_arc option determines whether the large arc, i.e. the one spanning more than 180 degrees, is used (+true+) or the small arc (+false+).

The clockwise option determines if the arc is drawn in the counterclockwise direction (+false+) or in the clockwise direction (+true+).

Any arguments not specified are not modified and retain their old value, see #initialize for the inital values.

Returns self.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc)
arc.configure(x: 50, y: 20, a: 30, b: 10)
canvas.move_to(0, 0).draw(arc).stroke


207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 207

def configure(x: nil, y: nil, a: nil, b: nil, inclination: nil, large_arc: nil,
              clockwise: nil, max_curves: nil)
  @x = x if x
  @y = y if y
  @a = a.abs if a
  @b = b.abs if b
  @inclination = inclination % 360 if inclination
  @large_arc = large_arc unless large_arc.nil?
  @clockwise = clockwise unless clockwise.nil?
  @max_curves = max_curves if max_curves

  self
end

#draw(canvas) ⇒ Object

Draws the arc on the given Canvas.

Since this method doesn't have any other arguments than canvas, it is usually better and easier to use Canvas#draw.

Examples:

#>pdf-center
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 10)
canvas.move_to(-20, -20)
arc.draw(canvas)
canvas.stroke


233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 233

def draw(canvas)
  x1, y1 = *canvas.current_point

  # ARC F.6.2 - nothing to do if endpoint is equal to current point
  return if float_equal(x1, @x) && float_equal(y1, @y)

  if @a == 0 || @b == 0
    # ARC F.6.2, F.6.6 - just use a line if it is not really an arc
    canvas.line_to(@x, @y)
  else
    values = compute_arc_values(x1, y1)
    arc = canvas.graphic_object(:arc, **values)
    arc.draw(canvas, move_to_start: false)
  end
end