Merge pull request #1529 from inclement/circle_drawing

Fixed angle_end/start with new circle drawing algorithm
This commit is contained in:
Mathieu Virbel 2013-10-04 10:19:44 -07:00
commit 65a97bffa9
2 changed files with 65 additions and 51 deletions

View File

@ -4,9 +4,11 @@ from kivy.app import App
from kivy.lang import Builder
kv = '''
FloatLayout:
BoxLayout:
orientation: 'vertical'
BoxLayout:
size_hint_y: None
height: sp(100)
BoxLayout:
orientation: 'vertical'
Slider:
@ -14,7 +16,7 @@ FloatLayout:
min: -360.
max: 360.
Label:
text: '{}'.format(e1.value)
text: 'angle_start = {}'.format(e1.value)
BoxLayout:
orientation: 'vertical'
Slider:
@ -23,19 +25,41 @@ FloatLayout:
max: 360.
value: 360
Label:
text: '{}'.format(e2.value)
text: 'angle_end = {}'.format(e2.value)
ToggleButton:
id: e3
text: 'Fast algo\\n(width == height)' if self.state == 'normal' else 'Normal algo\\n(width != height)'
FloatLayout
BoxLayout:
size_hint_y: None
height: sp(100)
BoxLayout:
orientation: 'vertical'
Slider:
id: wm
min: 0
max: 2
value: 1
Label:
text: 'Width mult. = {}'.format(wm.value)
BoxLayout:
orientation: 'vertical'
Slider:
id: hm
min: 0
max: 2
value: 1
Label:
text: 'Height mult. = {}'.format(hm.value)
Button:
text: 'Reset ratios'
on_press: wm.value = 1; hm.value = 1
FloatLayout:
canvas:
Color:
rgb: 1, 1, 1
Ellipse:
pos: 100, 100
size: 200, 201 if e3.state == 'down' else 200
size: 200 * wm.value, 201 * hm.value
source: 'data/logo/kivy-icon-512.png'
angle_start: e1.value
angle_end: e2.value

View File

@ -864,9 +864,9 @@ cdef class Ellipse(Rectangle):
# rad = deg * (pi / 180), where pi / 180 = 0.0174...
angle_start = self._angle_start * 0.017453292519943295
angle_end = self._angle_end * 0.017453292519943295
angle_range = abs(angle_end - angle_start) / self._segments
angle_range = -1 * (angle_end - angle_start) / self._segments
# add start vertice in the middle
# add start vertex in the middle
x = self.x + rx
y = self.y + ry
ttx = ((x - self.x) / self.w) * tw + tx
@ -877,48 +877,36 @@ cdef class Ellipse(Rectangle):
vertices[0].t0 = tty
indices[0] = 0
# super fast ellipse drawing
# credit goes to: http://slabode.exofire.net/circle_draw.shtml
tangetial_factor = tan(angle_range)
radial_factor = cos(angle_range)
if rx == ry and self.angle_start == 0 and self.angle_end == 360:
# super fast version
# credits goes to: http://slabode.exofire.net/circle_draw.shtml
# there is few issues with angle, so until fixed, allow this to work
# only on "default" ellipse
tangetial_factor = tan(angle_range)
radial_factor = cos(angle_range)
cx = self.x + rx
cy = self.y + ry
x = rx * sin(angle_start)
y = rx * cos(angle_start)
# Calculate the coordinates for a circle with radius 0.5 about
# the point (0.5, 0.5). Only stretch to an ellipse later.
cx = 0.5
cy = 0.5
r = 0.5
x = r * sin(angle_start)
y = r * cos(angle_start)
for i in xrange(1, count + 2):
ttx = ((rx + x) / self.w) * tw + tx
tty = ((ry + y) / self.h) * th + ty
vertices[i].x = cx + x
vertices[i].y = cy + y
vertices[i].s0 = ttx
vertices[i].t0 = tty
indices[i] = i
for i in xrange(1, count + 2):
ttx = (cx + x) * tw + tx
tty = (cy + y) * th + ty
real_x = self.x + (cx + x) * self.w
real_y = self.y + (cy + y) * self.h
vertices[i].x = real_x
vertices[i].y = real_y
vertices[i].s0 = ttx
vertices[i].t0 = tty
indices[i] = i
fx = -y
fy = x
x += fx * tangetial_factor
y += fy * tangetial_factor
x *= radial_factor
y *= radial_factor
else:
for i in xrange(1, count + 2):
angle = angle_start + (angle_dir * (i - 1) * angle_range)
x = (self.x + rx) + (rx * sin(angle))
y = (self.y + ry) + (ry * cos(angle))
ttx = ((x - self.x) / self.w) * tw + tx
tty = ((y - self.y) / self.h) * th + ty
vertices[i].x = x
vertices[i].y = y
vertices[i].s0 = ttx
vertices[i].t0 = tty
indices[i] = i
fx = -y
fy = x
x += fx * tangetial_factor
y += fy * tangetial_factor
x *= radial_factor
y *= radial_factor
self.batch.set_data(vertices, count + 2, indices, count + 2)
@ -952,3 +940,5 @@ cdef class Ellipse(Rectangle):
self._angle_end = value
self.flag_update()