From f202619ebe4230e7059ed83b54e59f1496763554 Mon Sep 17 00:00:00 2001 From: Michael Schindler Date: Tue, 14 Feb 2006 19:09:22 +0000 Subject: [PATCH] pyx/connector.py git-svn-id: https://pyx.svn.sourceforge.net/svnroot/pyx/trunk/pyx@2556 069f4177-920e-0410-937b-c2a4a81bcd90 --- CHANGES | 1 + manual/connector.py | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ manual/connector.tex | 58 ++++++++++++++++--------- 3 files changed, 157 insertions(+), 21 deletions(-) create mode 100755 manual/connector.py diff --git a/CHANGES b/CHANGES index 34f0ea1e..0a008216 100644 --- a/CHANGES +++ b/CHANGES @@ -142,6 +142,7 @@ TODO for 0.9: - allow arrows at arbitrary positions along the path (TODO: check documentation) - connector module: - boxdists parameter need to be a list/tuple of two items now + - changed the orientation of the angle parameters - trafo module: - renamed _apply to apply_pt - introduce _epsilon for checking the singularity of a trafo diff --git a/manual/connector.py b/manual/connector.py new file mode 100755 index 00000000..56e520f6 --- /dev/null +++ b/manual/connector.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: ISO-8859-15 -*- +import sys +sys.path.insert(0, "..") +from math import * +from pyx import * + +startbox = box.polygon(corners=[[0,-0.6], [0.5,0.1], [-0.25,0.1]]) +endbox = box.polygon(corners=[[4.5,3.9], [5.5,4.0], [5.2,3.4]]) + +# the arc connector <<< +c1 = canvas.canvas() +for b in [startbox, endbox]: + c1.stroke(b.path(), [style.linewidth.Thick, style.linejoin.round]) + c1.fill(path.circle_pt(b.center[0], b.center[1], 2)) +absangle = degrees(atan2(endbox.center[1] - startbox.center[1], endbox.center[0] - startbox.center[0])) +relangle = 60 +len = 2 + +# the direct connection +direct = path.line_pt(startbox.center[0], startbox.center[1], endbox.center[0], endbox.center[1]) +c1.stroke(direct, [style.linestyle.dashed]) + +# the arc connector +l = connector.arc(startbox, endbox, relangle=relangle, boxdists=[0.0,0.0]) +c1.stroke(l, [style.linewidth.Thick, color.rgb.red, deco.earrow.Large]) + +# the relangle parameter +comp1 = path.path(path.moveto(*direct.atbegin()), + path.rlineto(len*cos(radians(absangle + relangle)), len*sin(radians(absangle + relangle)))) +c1.stroke(comp1) +ang = path.path(path.arc(direct.atbegin()[0], direct.atbegin()[1], 0.8*len, absangle, absangle+relangle)) +c1.stroke(ang, [deco.earrow.large]) +pos = ang.at(0.5*ang.arclen()) +c1.text(pos[0], pos[1], r"~relangle", [text.halign.left]) + +# the bulge parameter +bulge = 0.5 * direct.arclen() * tan(0.5*radians(relangle)) +bul = path.path(path.moveto(*direct.at(0.5*direct.arclen())), + path.rlineto(bulge * cos(radians(absangle+90)), bulge * sin(radians(absangle+90)))) +c1.stroke(bul, [deco.earrow.large]) +pos = bul.at(0.5*bul.arclen()) +c1.text(pos[0], pos[1], r"~(rel)bulge", [text.halign.left]) + +# >>> + +# the curve connector <<< +c2 = canvas.canvas() +for b in [startbox, endbox]: + c2.stroke(b.path(), [style.linewidth.Thick, style.linejoin.round]) + c2.fill(path.circle_pt(b.center[0], b.center[1], 2)) +absangle = degrees(atan2(endbox.center[1] - startbox.center[1], endbox.center[0] - startbox.center[0])) +relangle1 = 60 +relangle2 = 30 +absbulge = 0 +relbulge = 0.5 +len = 2 + +# the direct connection +direct = path.line_pt(startbox.center[0], startbox.center[1], endbox.center[0], endbox.center[1]) +c2.stroke(direct, [style.linestyle.dashed]) + +# the arc connector +l = connector.curve(startbox, endbox, relangle1=relangle1, relangle2=relangle2, absbulge=absbulge, relbulge=relbulge, boxdists=[0.0,0.0]) +#l = connector.curve(startbox, endbox, absangle1=absangle+relangle1, absangle2=absangle+relangle2, absbulge=absbulge, relbulge=relbulge, boxdists=[0.0,0.0]) +c2.stroke(l, [style.linewidth.Thick, color.rgb.red, deco.earrow.Large]) + +# the relangle parameters +# relangle1 +c2.stroke(path.path(path.moveto(*direct.atbegin()), + path.rlineto(len*cos(radians(absangle + relangle1)), + len*sin(radians(absangle + relangle1))))) +ang = path.path(path.arc(direct.atbegin()[0], direct.atbegin()[1], 0.8*len, absangle, absangle+relangle1)) +c2.stroke(ang, [deco.earrow.large]) +pos = ang.at(0.5*ang.arclen()) +c2.text(pos[0], pos[1], r"~relangle1", [text.halign.left]) + +# absangle1 +c2.stroke(path.path(path.moveto(*direct.atbegin()), path.rlineto(len, 0))) +ang = path.path(path.arc(direct.atbegin()[0], direct.atbegin()[1], 0.5*len, 0, absangle+relangle1)) +c2.stroke(ang, [deco.earrow.large]) +pos = ang.at(0.2*ang.arclen()) +c2.text(pos[0], pos[1], r"~absangle1", [text.halign.left]) + +# relangle2 +c2.stroke(path.path(path.moveto(*direct.atend()), + path.rlineto(len*cos(radians(absangle)), + len*sin(radians(absangle))))) +c2.stroke(path.path(path.moveto(*direct.atend()), + path.rlineto(len*cos(radians(absangle + relangle2)), + len*sin(radians(absangle + relangle2))))) +ang = path.path(path.arc(direct.atend()[0], direct.atend()[1], + 0.8*len, absangle, absangle+relangle2)) +c2.stroke(ang, [deco.earrow.large]) +pos = ang.at(0.5*ang.arclen()) +c2.text(pos[0], pos[1], r"~relangle2", [text.halign.left]) + +# the bulge parameter +bulge = absbulge + direct.arclen() * relbulge +bul = path.path(path.moveto(*direct.atbegin()), + path.rlineto(bulge * cos(radians(absangle+relangle1)), bulge * sin(radians(absangle+relangle1)))) +c2.stroke(bul, [deco.earrow.large]) +pos = bul.at(0.7*bul.arclen()) +c2.text(pos[0], pos[1], r"~(rel)bulge", [text.halign.left]) + +bul = path.path(path.moveto(*direct.atend()), + path.rlineto(-bulge * cos(radians(absangle+relangle2)), -bulge * sin(radians(absangle+relangle2)))) +c2.stroke(bul, [deco.earrow.large]) +pos = bul.at(0.7*bul.arclen()) +c2.text(pos[0], pos[1], r"~(rel)bulge", [text.halign.left, text.vshift(1)]) +# >>> + + +# write everything +c1.insert(c2, [trafo.translate(6.5, 0)]) +c1.writeEPSfile("connector", paperformat=document.paperformat.A4) +c1.writePDFfile("connector") + +# vim:foldmethod=marker:foldmarker=<<<,>>> diff --git a/manual/connector.tex b/manual/connector.tex index 696def41..114dde30 100644 --- a/manual/connector.tex +++ b/manual/connector.tex @@ -2,14 +2,22 @@ \label{connector} This module provides classes for connecting two \class{box}-instances with -lines, arcs or curves. -All constructors of the following connector-classes take two -\class{box}-instances as first arguments. They return a -\class{normpath}-instance from the first to the second box, starting/ending at -the boxes' outline. The behaviour of the path is determined by the -boxes' center and some angle- and distance-keywords. The resulting \class{connector} will -additionally be shortened by lengths given in the \keyword{boxdists}-keyword (a -list of two lengths, default \code{[0,0]}). +lines, arcs or curves. All constructors of the following connector-classes take +two \class{box}-instances as the two first arguments. They return a connecting +path from the first to the second box. The overall geometry of the path is such +that is starts/ends at the boxes' centers. It is then cut by the boxes' +outlines. The resulting \class{connector} will additionally be shortened by +lengths given in the \keyword{boxdists}-keyword (a list of two lengths, default +\code{[0,0]}). + +Angle keywords can be either absolute or relative. The absolute angles refer to +the angle between x-axis and the running tangent of the connector, while the +relative angles are between the direct connecting line of the box-centers and +the running tangent (see figure.~\ref{fig:connector}). + +The bulge-keywords parameterize the deviation of the connector from the +connecting line. It has different meanings for different connectors (see +figure.~\ref{fig:connector}). \section{Class \class{line}} @@ -18,19 +26,22 @@ The constructor of the \class{line} class accepts only boxes and the \section{Class \class{arc}} -The constructor also takes either the \keyword{relangle}-keyword or a -combination of \keyword{relbulge} and \keyword{absbulge}. The ``bulge'' is the -meant to be a hint of the greatest distance between the connecting arc and the -straight connecting line. (Default: \code{relangle=45}, -\code{relbulge=None}, \code{absbulge=None})\medskip +The constructor takes either the \keyword{relangle}-keyword or a +combination of \keyword{relbulge} and \keyword{absbulge}. The ``bulge'' is +meant to be a hint for the greatest distance between the connecting arc and the +straight connection between the box-centers. (Default: \code{relangle=45}, +\code{relbulge=None}, \code{absbulge=None})\smallskip -Note that the bulge-keywords override the angle-keyword. When both -\keyword{relbulge} and \keyword{absbulge} are given they will be added. +Note that the bulge-keywords override the angle-keyword. + +If both \keyword{relbulge} and \keyword{absbulge} are given, they will be +added. \section{Class \class{curve}} The constructor takes both angle- and bulge-keywords. Here, the bulges are -used as distances between bezier-curve control points:\medskip +used as distances between the control points of the cubic Bezi\'er-curve. +For the signs of the angle- and bulge-keywords refer to figure~\ref{fig:connector}. \keyword{absangle1} or \keyword{relangle1}\\ \keyword{absangle2} or \keyword{relangle2}, where the absolute angle overrides the @@ -41,11 +52,15 @@ relative if both are given. (Default: \code{relangle1=45}, given.\\ (Default: \code{absbulge=None}, \code{relbulge=0.39}; these default values produce output similar to the defaults of \class{arc}.)\medskip -Note that relative angle-keywords are counted in the following way: -\keyword{relangle1} is counted in negative direction, starting at the straight -connector line, and \keyword{relangle2} is counted in positive direction. -Therefore, the outcome with two positive relative angles will always leave the -straight connector at its left and will not cross it. + +\begin{figure}[hbt] +\centerline{ +\includegraphics{connector} +} +\caption{The angle-parameters of the connector.arc (left panel) and the +connector.curve (right panel) classes.} +\label{fig:connector} +\end{figure} \section{Class \class{twolines}} @@ -62,3 +77,4 @@ all five angles are \code{None})\medskip \keyword{length1} and \keyword{length2} for the lengths of the connecting lines. (Default: \code{None}) + -- 2.11.4.GIT