# Source code for kiva.arc_conversion

```# (C) Copyright 2005-2022 Enthought, Inc., Austin, TX
#
# This software is provided without warranty under the terms of the BSD
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
from math import acos, atan2

from numpy import array, dot, pi, sin, sqrt

[docs]def two_point_arc_to_kiva_arc(p1, p2, theta):
"""
Converts an arc in two point and subtended angle  format (startpoint,
endpoint, theta (positive for ccw, negative for cw)) into kiva format
(x, y, radius, start_angle, end_angle, cw)
"""

chord = p2 - p1
chordlen = sqrt(dot(chord, chord))
radius = abs(chordlen / (2 * sin(theta / 2)))
altitude = sqrt(pow(radius, 2) - pow(chordlen / 2, 2))
if theta > pi or theta < 0:
altitude = -altitude
chordmidpoint = (p1 + p2) / 2
rotate90 = array(((0.0, -1.0), (1.0, 0.0)))
centerpoint = dot(rotate90, (chord / chordlen)) * altitude + chordmidpoint

start_angle = atan2(*(p1 - centerpoint)[::-1])
end_angle = start_angle + theta
if theta < 0:
start_angle, end_angle, = end_angle, start_angle
cw = False
return (centerpoint, centerpoint, radius, start_angle, end_angle, cw)

""" Given a starting point, two endpoints of a line segment, and a radius,
calculate the tangent points for arc_to().
"""

def normalize_vector(x, y):
""" Given a vector, return its unit length representation.
"""
length = sqrt(x ** 2 + y ** 2)
if length <= 1e-6:
return (0.0, 0.0)
return (x / length, y / length)

# calculate the angle between the two line segments
v1 = normalize_vector(start - p1, start - p1)
v2 = normalize_vector(p2 - p1, p2 - p1)
angle = acos(v1 * v2 + v1 * v2)

# punt if the half angle is zero or a multiple of pi
sin_half_angle = sin(angle / 2.0)
if sin_half_angle == 0.0:
return (p1, p2)

# calculate the distance from p1 to the center of the arc