rpms/ipe/F-7 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:53 UTC 2007


Author: rineau

Update of /cvs/pkgs/rpms/ipe/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv21275/F-7

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/F-7/ipe.spec,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- ipe.spec	27 Aug 2007 19:55:37 -0000	1.13
+++ ipe.spec	17 Sep 2007 19:55:20 -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