rpms/ipe/FC-6 ipe-6.0pre28-patch1.patch, NONE, 1.1 ipe.spec, 1.13, 1.14
Laurent Rineau (rineau)
fedora-extras-commits at redhat.com
Mon Sep 17 19:55:56 UTC 2007
Author: rineau
Update of /cvs/pkgs/rpms/ipe/FC-6
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv21275/FC-6
Modified Files:
ipe.spec
Added Files:
ipe-6.0pre28-patch1.patch
Log Message:
* Mon Sep 17 2007 Laurent Rineau <laurent.rineau__fedora at normalesup.org> - 6.0-0.21.pre28%{?dist}
- New upstream patch.
ipe-6.0pre28-patch1.patch:
--- NEW FILE ipe-6.0pre28-patch1.patch ---
diff -r -u ipe-6.0pre28/src/include/ipegeo.h ipe-6.0pre28-patch1/src/include/ipegeo.h
--- ipe-6.0pre28/src/include/ipegeo.h 2006-12-23 16:05:08.000000000 +0100
+++ ipe-6.0pre28-patch1/src/include/ipegeo.h 2007-09-17 17:06:45.000000000 +0200
@@ -251,7 +251,8 @@
static void ClosedSpline(int n, const IpeVector *v,
std::vector<IpeBezier> &result);
bool Intersects(const IpeLine &l, IpeVector &pt) const;
- bool Intersects(const IpeSegment &l, IpeVector &pt) const;
+ bool Intersects(const IpeSegment &l, std::vector<IpeVector> &result) const;
+ bool Intersects(const IpeBezier &b, std::vector<IpeVector> &result) const;
public:
IpeVector iV[4];
};
@@ -312,7 +313,16 @@
IpeVector &pos, IpeAngle &angle);
IpeRect BBox() const;
bool Intersects(const IpeLine &l, IpeVector &pt) const;
- bool Intersects(const IpeSegment &l, IpeVector &pt) const;
+ bool Intersects(const IpeSegment &s, std::vector<IpeVector> &result) const;
+ bool Intersects(const IpeArc &a, std::vector<IpeVector> &result) const;
+ bool Intersects(const IpeBezier &b, std::vector<IpeVector> &result) const;
+
+private:
+ void Subdivide(IpeArc &l, IpeArc &r) const;
+ bool Straight(const double precision) const;
+ void GetCPs(IpeVector &start, IpeVector &end) const;
+ void AsSegment(IpeSegment &seg) const;
+
public:
IpeMatrix iM;
IpeAngle iAlpha;
diff -r -u ipe-6.0pre28/src/ipelib/ipegeo.cpp ipe-6.0pre28-patch1/src/ipelib/ipegeo.cpp
--- ipe-6.0pre28/src/ipelib/ipegeo.cpp 2006-12-23 16:05:08.000000000 +0100
+++ ipe-6.0pre28-patch1/src/ipelib/ipegeo.cpp 2007-09-17 17:06:45.000000000 +0200
@@ -691,18 +691,108 @@
box.Max() + IpeVector(0.5, 0.5));
}
+
+
+/* Determines intersection point(s) of two cubic Bezier-Splines.
+ * The found intersection points are stored in the vector intersections.
+ */
+void IntersectBeziers(std::vector<IpeVector> &intersections,
+ IpeBezier &a,
+ IpeBezier &b) {
+ /* Recursive approximation procedure to find intersections:
+ * If the bounding boxes of two Beziers overlap, both are subdivided,
+ * each one into two partial Beziers.
+ * In the next recursion steps, it is checked if the bounding boxes
+ * of the partial Beziers overlap. If they do, they are subdivided
+ * again and so on, until a special precision is achieved:
+ * Then the Beziers are converted to Segments and checked for intersection.
+ *
+ * Intersection points that lie near the first or last control point
+ * of a bezier (have a distance of less than MIN_DIST to a cp) are ignored;
+ * this is to avoid connection points of two beziers accidentaly being
+ * misinterpreted as intersections.
+ */
+
+ double PRECISION = 1.0;
+ double MIN_DIST = 0.05;
+
+ a = a; b = b; intersections = intersections;
+
+ IpeRect bboxA = a.BBox();
+ IpeRect bboxB = b.BBox();
+
+ if (!bboxA.Intersects(bboxB)) {
+ return;
+ }
+
+ if (a.Straight(PRECISION) && b.Straight(PRECISION)) {
+ // Recursion anchor!
+
+ IpeSegment aLine = IpeSegment(a.iV[0], a.iV[3]);
+ IpeSegment bLine = IpeSegment(b.iV[0], b.iV[3]);
+
+ IpeVector p;
+
+ if (aLine.Intersects(bLine, p)) {
+ /* We found an intersection point.
+ * If this point is too close to one of the outer control
+ * points, it is ignorated.
+ */
+
+ if ((p-a.iV[0]).Len() < MIN_DIST ||
+ (p-a.iV[3]).Len() < MIN_DIST ||
+ (p-b.iV[0]).Len() < MIN_DIST ||
+ (p-b.iV[3]).Len() < MIN_DIST) {
+ //Ignoring intersection too close to control point.
+ } else {
+ //Found intersection (p.iX, p.iY)
+ intersections.push_back(p);
+ }
+ }
+
+ return;
+ }
+
+ IpeBezier leftA, rightA, leftB, rightB;
+ a.Subdivide(leftA, rightA);
+ b.Subdivide(leftB, rightB);
+
+ IntersectBeziers(intersections, leftA, leftB);
+ IntersectBeziers(intersections, rightA, leftB);
+ IntersectBeziers(intersections, leftA, rightB);
+ IntersectBeziers(intersections, rightA, rightB);
+}
+
+
+
bool IpeBezier::Intersects(const IpeLine &, IpeVector &) const
{
// XXX
return false;
}
-bool IpeBezier::Intersects(const IpeSegment &, IpeVector &) const
+/* Returns intersection point(s) of Bezier with Segment
+ */
+bool IpeBezier::Intersects(const IpeSegment &s, std::vector<IpeVector> &result) const
{
- // XXX
- return false;
+ //convert Segment to Bezier and use Bezier-Bezier-intersection check
+ IpeBezier b2(s.iQ, s.iQ, s.iP, s.iP);
+ IpeBezier b1 = (*this);
+ IntersectBeziers(result, b1, b2);
+ return (result.size()>=1);
}
+/* Returns intersection point(s) of Bezier with Bezier
+ */
+bool IpeBezier::Intersects(const IpeBezier &b, std::vector<IpeVector> &result) const
+{
+ IpeBezier b2 = b;
+ IpeBezier b1 = (*this);
+ IntersectBeziers(result, b1, b2);
+ return (result.size()>=1);
+}
+
+
// --------------------------------------------------------------------
/*! \class IpeArc
@@ -813,10 +903,198 @@
return false;
}
-bool IpeArc::Intersects(const IpeSegment &, IpeVector &) const
+// --------------------------------------------------------------------
+
+/* Returns intersection point(s) of Arc with Segment
+ */
+bool IpeArc::Intersects(const IpeSegment &s, std::vector<IpeVector> &result) const
{
- // XXX
- return false;
+ //First convert the Segment to a Bezier, then check Arc-Bezier-intersection
+ IpeBezier b(s.iQ, s.iQ, s.iP, s.iP);
+ return Intersects(b, result);
+}
+
+/* Returns intersection point(s) of Arc with Arc
+ */
+bool IpeArc::Intersects(const IpeArc &a, std::vector<IpeVector> &result) const
+{
+ /* Recursive approximation procedure to find intersections:
+ * If the bounding boxes of two Arcs overlap, both are subdivided,
+ * each one into two partial Arcs.
+ * In the next recursion steps, it is checked if the bounding boxes
+ * of the partial Arcs overlap. If they do, they are subdivided
+ * again and so on, until a special precision is achieved.
+ */
+
+ const double PRECISION = 0.05; //0.05 is about ~2.8647 degrees
+
+ if (!BBox().Intersects(a.BBox())) {
+ return false;
+ }
+
+ if (Straight(PRECISION) && a.Straight(PRECISION)) {
+ IpeSegment segThis, segA;
+ IpeVector pt;
+
+ AsSegment(segThis);
+ a.AsSegment(segA);
+
+ if (segThis.Intersects(segA, pt)) {
+ result.push_back(pt);
+ return true;
+ } else
+ return false;
+ }
+
+ IpeArc al, ar;
+ Subdivide(al, ar);
+ IpeArc bl, br;
+ a.Subdivide(bl, br);
+
+ al.Intersects(bl, result);
+ al.Intersects(br, result);
+ ar.Intersects(bl, result);
+ ar.Intersects(br, result);
+
+ return result.size() > 0;
+}
+
+/* Returns intersection point(s) of Arc with Bezier
+ */
+bool IpeArc::Intersects(const IpeBezier &b, std::vector<IpeVector> &result) const
+{
+ /* Recursive approximation procedure to find intersections:
+ * If the bounding boxes of the Bezier and the Arc overlap, both are
+ * subdivided, the Bezier into two Beziers and the Arc into two Arcs.
+ * In the next recursion steps, it is checked if a bounding box
+ * of a partial Bezier overlap one of a partial Arc. If they overlap,
+ * they are subdivided again and so on, until a special precision is achieved.
+ */
+
+ const double PRECISION = 0.05; //0.05 is about ~2.8647 degrees
+
+ if (!BBox().Intersects(b.BBox())) {
+ return false;
+ }
+
+ if (Straight(PRECISION) && b.Straight(PRECISION)) {
+ IpeSegment segThis, segB;
+ IpeVector pt;
+
+ AsSegment(segThis);
+ segB = IpeSegment(b.iV[0], b.iV[3]);
+
+ if (segThis.Intersects(segB, pt)) {
+ result.push_back(pt);
+ return true;
+ } else
+ return false;
+ }
+
+ IpeArc al, ar;
+ Subdivide(al, ar);
+ IpeBezier bl, br;
+ b.Subdivide(bl, br);
+
+ al.Intersects(bl, result);
+ al.Intersects(br, result);
+ ar.Intersects(bl, result);
+ ar.Intersects(br, result);
+
+ return result.size() > 0;
+}
+
+/* Subdivide this arc into two.
+ */
+void IpeArc::Subdivide(IpeArc &l, IpeArc &r) const
+{
+ double gamma;
+ double alpha = (double) iAlpha,
+ beta = (double) iBeta;
+
+ /* This works as following:
+ * alpha is the start- and beta the endangle of the arc.
+ * We ensure that both are positive and that
+ * alpha < beta. Then the angle gamma that lies exactly
+ * between alpha and beta is calculated.
+ * Two new arcs are created: One from alpha to gamma
+ * and one from gamma to beta.
+ *
+ * XXX This might result in orientation information not
+ * being passed to the subdivided arcs!
+ */
+
+ if (alpha == 0.0 && beta == 0.0) {
+ alpha = -M_PI;
+ beta = M_PI;
+ }
+
+ if (alpha < 0.0)
+ alpha += 2*M_PI;
+
+ if (beta < 0.0)
+ beta += 2*M_PI;
+
+ if (alpha > beta)
+ beta += 2*M_PI;
+
+ gamma = alpha + (beta - alpha) / 2.0;
+
+ if (gamma >= 2*M_PI)
+ gamma -= 2*M_PI;
+
+ if (gamma > M_PI)
+ gamma -= 2*M_PI;
+
+ l = IpeArc(iM, iAlpha, IpeAngle(gamma));
+ r = IpeArc(iM, IpeAngle(gamma), iBeta);
+}
+
+/* Returns true if the difference between start- and
+ * endangle is less than precision.
+ */
+bool IpeArc::Straight(const double precision) const
+{
+ double alpha = (double) iAlpha,
+ beta = (double) iBeta,
+ diff;
+
+ if (alpha == 0.0 && beta == 0.0)
+ return false;
+
+ if (alpha < 0.0)
+ alpha += 2*M_PI;
+
+ if (beta < 0.0)
+ beta += 2*M_PI;
+
+ diff = beta - alpha;
+ diff = diff < .0 ? -diff : diff;
+
+ return diff < precision;
}
+/* Return the start- and endpoint of the arc.
+ */
+void IpeArc::GetCPs(IpeVector &start, IpeVector &end) const {
+ double alpha, beta;
+
+ alpha = (double) iAlpha;
+ beta = (double) iBeta;
+
+ start = (iM * IpeVector(cos(alpha), sin(alpha)));
+ end = (iM * IpeVector(cos(beta), sin(beta)));
+}
+
+/* Approximate the arc as a straight segment.
+ */
+void IpeArc::AsSegment(IpeSegment &seg) const {
+ IpeVector start, end;
+
+ GetCPs(start, end);
+
+ seg = IpeSegment(start, end);
+}
+
+
// --------------------------------------------------------------------
diff -r -u ipe-6.0pre28/src/ipelib/ipesnap.cpp ipe-6.0pre28-patch1/src/ipelib/ipesnap.cpp
--- ipe-6.0pre28/src/ipelib/ipesnap.cpp 2006-12-23 16:05:08.000000000 +0100
+++ ipe-6.0pre28-patch1/src/ipelib/ipesnap.cpp 2007-09-17 17:06:45.000000000 +0200
@@ -194,7 +194,8 @@
IpeVector pos1 = pos;
IpeVector v;
double d1;
-
+
+ //1. Perform seg-seg-intersection snapping
for (uint i = 0; i < segs.iSegs.size(); i++) {
for (uint j = i+1; j < segs.iSegs.size(); j++) {
if (segs.iSegs[i].Intersects(segs.iSegs[j], v) &&
@@ -204,6 +205,81 @@
}
}
}
+
+ //2. Perform bezier-bezier-intersection snapping
+ std::vector<IpeVector> vv;
+ for (uint i = 0; i < segs.iBeziers.size(); i++) {
+ for (uint j = i+1; j < segs.iBeziers.size(); j++) {
+ if (segs.iBeziers[i].Intersects(segs.iBeziers[j], vv)) {
+ for (uint k = 0; k < vv.size(); k++) {
+ if ((d1 = (pos - (vv[k])).Len()) < d) {
+ d = d1;
+ pos1 = vv[k];
+ }
+ }
+ }
+ }
+ }
+
+ //3. Perform arc-arc-intersection snapping
+ //and arc-bezier-intersection snapping
+ for (uint i = 0; i < segs.iArcs.size(); i++) {
+ for (uint j = i+1; j < segs.iArcs.size(); j++) {
+ if (segs.iArcs[i].Intersects(segs.iArcs[j], vv)) {
+ for (uint k = 0; k < vv.size(); k++) {
+ if ((d1 = (pos - (vv[k])).Len()) < d) {
+ d = d1;
+ pos1 = vv[k];
+ }
+ }
+ }
+ }
+ vv.clear();
+
+ for (uint j=0;j<segs.iBeziers.size();j++) {
+ if (segs.iArcs[i].Intersects(segs.iBeziers[j], vv)) {
+ for (uint k=0;k<vv.size();k++) {
+ if ((d1 = (pos - (vv[k])).Len()) < d) {
+ d = d1;
+ pos1 = vv[k];
+ }
+ }
+ }
+ vv.clear();
+ }
+ }
+
+ //4. Perform bezier-seg-intersection snapping
+ vv.clear();
+ for (uint i = 0; i < segs.iBeziers.size(); i++) {
+ for (uint j = 0; j < segs.iSegs.size(); j++) {
+ if (segs.iBeziers[i].Intersects(segs.iSegs[j], vv)) {
+ for (uint k = 0; k < vv.size(); k++) {
+ if ((d1 = (pos - (vv[k])).Len()) < d) {
+ d = d1;
+ pos1 = vv[k];
+ }
+ }
+ }
+ }
+ }
+
+
+ //5. Perform arc-seg-intersection snapping
+ vv.clear();
+ for (uint i = 0; i < segs.iArcs.size(); i++) {
+ for (uint j = 0; j < segs.iSegs.size(); j++) {
+ if (segs.iArcs[i].Intersects(segs.iSegs[j], vv)) {
+ for (uint k = 0; k < vv.size(); k++) {
+ if ((d1 = (pos - (vv[k])).Len()) < d) {
+ d = d1;
+ pos1 = vv[k];
+ }
+ }
+ }
+ }
+ }
+
if (d < snapDist) {
pos = pos1;
return true;
Index: ipe.spec
===================================================================
RCS file: /cvs/pkgs/rpms/ipe/FC-6/ipe.spec,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- ipe.spec 27 Aug 2007 19:55:40 -0000 1.13
+++ ipe.spec 17 Sep 2007 19:55:24 -0000 1.14
@@ -2,14 +2,15 @@
Name: ipe
Version: 6.0
-Release: 0.20.pre%{preversion}%{?dist}
+Release: 0.21.pre%{preversion}%{?dist}
Summary: The Ipe extensible drawing editor
Group: Applications/Publishing
License: GPLv2+
URL: http://tclab.kaist.ac.kr/ipe/
Source0: http://tclab.kaist.ac.kr/ipe/%{name}-%{version}pre%{preversion}-src.tar.gz
-Patch0: ipe-6.0pre28-no-freetype-version-check.patch
+Patch10: ipe-6.0pre28-no-freetype-version-check.patch
+Patch100: ipe-6.0pre28-patch1.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: qt4-devel
@@ -23,7 +24,7 @@
Requires: urw-fonts
Requires: htmlview
-Provides: ipe(api) = 5.99.%{preversion}pre
+Provides: ipe(api) = 5.99.%{preversion}.1pre
%description
Ipe is a drawing editor for creating figures in PDF or (encapsulated)
@@ -50,7 +51,8 @@
%prep
%setup -n %{name}-%{version}pre%{preversion} -q
-%patch0 -p1 -b .no-freetype-check
+%patch10 -p1 -b .no-freetype-check
+%patch100 -p1 -b .pre28-patch1
%build
export QTDIR=%{qtdir}
@@ -148,6 +150,7 @@
%files devel
%doc readme.txt gpl.txt news.txt
%{_includedir}/*.h
+%exclude %{_includedir}/*.h.pre28-patch1
%{_libdir}/libipe.so
%{_libdir}/libipecanvas.so
%{_libdir}/libipemodel.so
@@ -157,6 +160,9 @@
%{_datadir}/ipe/%{version}/doc
%changelog
+* Mon Sep 17 2007 Laurent Rineau <laurent.rineau__fedora at normalesup.org> - 6.0-0.21.pre28%{?dist}
+- New upstream patch.
+
* Mon Aug 27 2007 Laurent Rineau <laurent.rineau__fedora at normalesup.org> - 6.0-0.20.pre28%{?dist}
- Change the URL, in Source0.
More information about the fedora-extras-commits
mailing list