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

Inherits:
Object
  • Object
show all
Includes:
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 collapse

EPSILON =

:nodoc:

1e-10

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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.



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

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


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

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


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

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