class HexaPDF::Content::GraphicObject::EndpointArc
web.archive.org/web/20160310153722/https://www.w3.org/TR/SVG/implnote.html).
version of about 2016, see
See: Arc, ARC - www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes (in the
canvas.move_to(0, 0).draw(arc).stroke
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 10)
#>pdf-center
Examples:
HexaPDF::Content::Canvas class.
This graphic object is registered under the :endpoint_arc key for use with the
use-case the path itself still has to be, for example, stroked.
Note that only the path of the arc itself is added to the canvas. So depending on the
with Arc.
the scenes the endpoint parameterization is turned into a center parameterization and drawn
generate an arc from the current point to a given point, similar to Canvas#line_to. Behind
This class describes an elliptical arc in endpoint parameterization. It allows one to
def self.configure(**kwargs)
Creates and configures a new endpoint arc object.
def self.configure(**kwargs) new.configure(**kwargs) end
def compute_angle_to_x_axis(vx, vy)
def compute_angle_to_x_axis(vx, vy) (vy < 0 ? -1 : 1) * rad_to_deg(Math.acos(vx / Math.sqrt(vx**2 + vy**2))) end
def compute_arc_values(x1, y1)
The argument (x1, y1) is the starting point.
Compute the center parameterization from the endpoint parameterization.
def compute_arc_values(x1, y1) x2 = @x y2 = @y rx = @a ry = @b theta = deg_to_rad(@inclination) cos_theta = Math.cos(theta) sin_theta = Math.sin(theta) # F.6.5.1 x1p = (x1 - x2) / 2.0 * cos_theta + (y1 - y2) / 2.0 * sin_theta y1p = (x1 - x2) / 2.0 * -sin_theta + (y1 - y2) / 2.0 * cos_theta x1ps = x1p**2 y1ps = y1p**2 rxs = rx**2 rys = ry**2 # F.6.6.2 l = x1ps / rxs + y1ps / rys if l > 1 rx *= Math.sqrt(l) ry *= Math.sqrt(l) rxs = rx**2 rys = ry**2 end # F.6.5.2 sqrt = (rxs * rys - rxs * y1ps - rys * x1ps) / (rxs * y1ps + rys * x1ps) sqrt = 0 if sqrt.abs < Utils::EPSILON sqrt = Math.sqrt(sqrt) sqrt *= -1 unless @large_arc == @clockwise cxp = sqrt * rx * y1p / ry cyp = - sqrt * ry * x1p / rx # F.6.5.3 cx = cos_theta * cxp - sin_theta * cyp + (x1 + x2) / 2.0 cy = sin_theta * cxp + cos_theta * cyp + (y1 + y2) / 2.0 # F.6.5.5 start_angle = compute_angle_to_x_axis((x1p - cxp), (y1p - cyp)) % 360 # F.6.5.6 (modified bc we just need the end angle) end_angle = compute_angle_to_x_axis((-x1p - cxp), (-y1p - cyp)) % 360 {cx: cx, cy: cy, a: rx, b: ry, start_angle: start_angle, end_angle: end_angle, inclination: @inclination, clockwise: @clockwise, max_curves: @max_curves} end
def configure(x: nil, y: nil, a: nil, b: nil, inclination: nil, large_arc: nil,
arc.configure(x: 50, y: 20, a: 30, b: 10)
arc = canvas.graphic_object(:endpoint_arc)
#>pdf-center
Examples:
Returns self.
for the inital values.
Any arguments not specified are not modified and retain their old value, see #initialize
(+false+) or in the clockwise direction (+true+).
The +clockwise+ option determines if the arc is drawn in the counterclockwise direction
180 degrees, is used (+true+) or the small arc (+false+).
The +large_arc+ option determines whether the large arc, i.e. the one spanning more than
* the given maximum number of approximation curves.
* the given clockwise flag and.
* the given large_arc flag,
* an inclination in respect to the x-axis of +inclination+ degrees,
* semi-minor axis +b+,
* semi-major axis +a+,
* endpoint (+x+, +y+),
Configures the endpoint arc with
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
def draw(canvas)
arc.draw(canvas)
canvas.move_to(-20, -20)
arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 10)
#>pdf-center
Examples:
easier to use Canvas#draw.
Since this method doesn't have any other arguments than +canvas+, it is usually better and
Draws the arc on the given Canvas.
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
def initialize
#>pdf-center
Examples:
large_arc=true, clockwise=false (a line to the origin).
Creates an endpoint arc with default values x=0, y=0, a=0, b=0, inclination=0,
def initialize @x = @y = 0 @a = @b = 0 @inclination = 0 @large_arc = true @clockwise = false @max_curves = nil end