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 - www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes (in the version of about 2016, see 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