#
# average_points.py - average coordinates of selected points
# Tamito KAJIYAMA <24 March 2000>
# Copyright (C) 2000 by Tamito KAJIYAMA
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from Sketch import CreatePath,Point,_
from Sketch.UI.sketchdlg import SKModal
from Tkinter import *
AVERAGE_BOTH = 0
AVERAGE_X = 1
AVERAGE_Y = 2
class AverageDialog(SKModal):
title = "Average Points"
def build_dlg(self):
self.var_which = IntVar(self.top)
self.var_which.set(AVERAGE_X)
label = Label(self.top, text="Average", anchor=W)
label.pack(fill=X)
button = Radiobutton(self.top, text="X Coordinates",
variable=self.var_which, value=AVERAGE_X,
anchor=W)
button.pack(fill=X)
button = Radiobutton(self.top, text="Y Coordinates",
variable=self.var_which, value=AVERAGE_Y,
anchor=W)
button.pack(fill=X)
button = Radiobutton(self.top, text="Both Coordinates",
variable=self.var_which, value=AVERAGE_BOTH,
anchor=W)
button.pack(fill=X)
button = Button(self.top, text="OK", command=self.ok)
button.pack(side=LEFT)
button = Button(self.top, text="Cancel", command=self.cancel)
button.pack(side=RIGHT)
def ok(self, *args):
self.close_dlg(self.var_which.get())
def average_points(context):
# find a bezier polygon selected
selection = []
for object in context.document.SelectedObjects():
if not object.is_Bezier:
continue
selection.append(object)
if len(selection) != 1:
context.application.MessageBox(title="Average Points",
message="Select one polygon.")
return None
# count selected points
object = selection[0]
object_paths = object.Paths()
npoints = 0
for path in object_paths:
for i in range(path.len):
if path.SegmentSelected(i):
npoints = npoints + 1
if npoints == 0:
context.application.MessageBox(title="Average Points",
message="Select two or more points.")
return None
# inquiry parameters
which = AverageDialog(context.application.root).RunDialog()
if which is None:
return None
# compute average coordinates of the selected points
ax = 0
ay = 0
modified_paths = []
for path in object_paths:
modified_paths.append([])
for i in range(path.len):
type, controls, point, cont = path.Segment(i)
modified_paths[-1].append([type, list(controls), point, cont])
if path.SegmentSelected(i):
ax = ax + point.x
ay = ay + point.y
ax = float(ax) / npoints
ay = float(ay) / npoints
# translate the selected points
for i in range(len(object_paths)):
path = object_paths[i]
new_path = modified_paths[i]
for j in range(path.len):
if path.SegmentSelected(j):
point = new_path[j][2]
if which == AVERAGE_X:
new_point = Point(ax, point.y)
elif which == AVERAGE_Y:
new_point = Point(point.x, ay)
else:
new_point = Point(ax, ay)
new_path[j][2] = new_point
offset = point - new_point
if len(new_path[j][1]) == 2:
new_path[j ][1][1] = new_path[j ][1][1] - offset
if j < path.len - 1 and len(new_path[j+1][1]) == 2:
new_path[j+1][1][0] = new_path[j+1][1][0] - offset
# create new paths
new_paths = []
for i in range(len(object_paths)):
path = object_paths[i]
new_path = CreatePath()
for type, controls, point, cont in modified_paths[i]:
new_path.AppendSegment(type, tuple(controls), point, cont)
if path.closed:
new_path.AppendLine(new_path.Node(0))
new_path.ClosePath()
new_paths.append(new_path)
# set the new paths
undo = object.SetPaths(new_paths)
# return Undo info
return undo
def run(context):
document = context.document
undo = average_points(context)
if undo is not None:
document.AddUndo(undo)
import Sketch.Scripting
Sketch.Scripting.AddFunction('average_points', 'Average Points', run,
script_type = Sketch.Scripting.AdvancedScript)
|