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 Content::Canvas#line_to.

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: GraphicObject::Arc, ARC - www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes

Constant Summary collapse

EPSILON =
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


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

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

Instance Attribute Details

#aObject (readonly)

Length of semi-major axis

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("red").move_to(0, 0).draw(arc, a: 40).stroke


97
98
99
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 97

def a
  @a
end

#bObject (readonly)

Length of semi-minor axis

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("red").move_to(0, 0).draw(arc, b: 50).stroke


107
108
109
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 107

def b
  @b
end

#clockwiseObject (readonly)

Direction of arc - if true in clockwise direction, else in counterclockwise direction

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("red").move_to(0, 0).draw(arc, clockwise: true).stroke


141
142
143
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 141

def clockwise
  @clockwise
end

#inclinationObject (readonly)

Inclination in degrees of semi-major axis in respect to x-axis

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("red").move_to(0, 0).draw(arc, inclination: 45).stroke


117
118
119
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 117

def inclination
  @inclination
end

#large_arcObject (readonly)

Large arc choice - if true 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("red").move_to(0, 0).draw(arc, large_arc: false, clockwise: true).stroke


128
129
130
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 128

def large_arc
  @large_arc
end

#xObject (readonly)

x-coordinate of endpoint

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("red").move_to(0, 0).draw(arc, x: -50).stroke


77
78
79
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 77

def x
  @x
end

#yObject (readonly)

y-coordinate of endpoint

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("red").move_to(0, 0).draw(arc, y: -20).stroke


87
88
89
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 87

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.



65
66
67
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 65

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) ⇒ 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 and

  • the given clockwise flag.

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.



177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 177

def configure(x: nil, y: nil, a: nil, b: nil, inclination: nil, large_arc: nil,
              clockwise: 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?

  self
end

#draw(canvas) ⇒ Object

Draws the arc on the given Canvas.



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/hexapdf/content/graphic_object/endpoint_arc.rb', line 191

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