Revision: 2148
http://synfig.svn.sourceforge.net/synfig/?rev=2148&view=rev
Author: dooglus
Date: 2008-11-04 14:45:34 +0000 (Tue, 04 Nov 2008)
Log Message:
-----------
Improve the rendering of curvegradient layers near vertices with zero-length
tangents. See http://dooglus.rincevent.net/random/arrow-old.png ,
http://dooglus.rincevent.net/random/arrow-new.png ,
http://dooglus.rincevent.net/random/arrow.sifz for an example of the various
types of glitch that have been fixed in this revision.
Modified Paths:
--------------
ETL/trunk/ETL/_bezier.h
synfig-core/trunk/src/modules/mod_gradient/curvegradient.cpp
Modified: ETL/trunk/ETL/_bezier.h
===================================================================
--- ETL/trunk/ETL/_bezier.h 2008-11-04 14:45:06 UTC (rev 2147)
+++ ETL/trunk/ETL/_bezier.h 2008-11-04 14:45:34 UTC (rev 2148)
@@ -553,8 +553,7 @@
bezier<V,T>::operator[](1),
bezier<V,T>::operator[](2),
bezier<V,T>::operator[](3)};
- float t = NearestPointOnCurve(x, array);
- return t > 0.999999 ? 0.999999 : t < 0.000001 ?
0.000001 : t;
+ return NearestPointOnCurve(x, array);
}
else
{
Modified: synfig-core/trunk/src/modules/mod_gradient/curvegradient.cpp
===================================================================
--- synfig-core/trunk/src/modules/mod_gradient/curvegradient.cpp
2008-11-04 14:45:06 UTC (rev 2147)
+++ synfig-core/trunk/src/modules/mod_gradient/curvegradient.cpp
2008-11-04 14:45:34 UTC (rev 2148)
@@ -50,6 +50,8 @@
/* === M A C R O S ========================================================= */
+#define FAKE_TANGENT_STEP 0.000001
+
/* === G L O B A L S ======================================================= */
SYNFIG_LAYER_INIT(CurveGradient);
@@ -306,7 +308,7 @@
// Calculate our values
p1=curve(t); // the closest point on the
curve
- tangent=deriv(t).norm(); // the unit tangent at that point
+ tangent=deriv(t); // the tangent at that point
// if the point we're nearest to is at either end of the
// bline, our distance from the curve is the distance from the
@@ -315,23 +317,64 @@
// this point
if (t<0.00001 || t>0.99999)
{
+ bool zero_tangent = (tangent[0] == 0 && tangent[1] ==
0);
+
if (t<0.5)
{
- if (iter->get_split_tangent_flag())
+ if (iter->get_split_tangent_flag() ||
zero_tangent)
{
-
tangent=(iter->get_tangent1().norm()+tangent).norm();
+ // fake the current tangent if we need
to
+ if (zero_tangent) tangent =
curve(FAKE_TANGENT_STEP) - curve(0);
+
+ // calculate the other tangent
+ Vector
other_tangent(iter->get_tangent1());
+ if (other_tangent[0] == 0 &&
other_tangent[1] == 0)
+ {
+ // find the previous blinepoint
+
std::vector<synfig::BLinePoint>::const_iterator prev;
+ if (iter != bline.begin())
(prev = iter)--;
+ else if (loop) (prev =
bline.end())--;
+ else prev = iter;
+
+ etl::hermite<Vector>
other_curve(prev->get_vertex(), iter->get_vertex(), prev->get_tangent2(),
iter->get_tangent1());
+ other_tangent = other_curve(1)
- other_curve(1-FAKE_TANGENT_STEP);
+ }
+
+ // normalise and sum the two tangents
+
tangent=(other_tangent.norm()+tangent.norm());
edge_case=true;
}
}
else
{
- if (next->get_split_tangent_flag())
+ if (next->get_split_tangent_flag() ||
zero_tangent)
{
-
tangent=(next->get_tangent2().norm()+tangent).norm();
+ // fake the current tangent if we need
to
+ if (zero_tangent) tangent = curve(1) -
curve(1-FAKE_TANGENT_STEP);
+
+ // calculate the other tangent
+ Vector
other_tangent(next->get_tangent2());
+ if (other_tangent[0] == 0 &&
other_tangent[1] == 0)
+ {
+ // find the next blinepoint
+
std::vector<synfig::BLinePoint>::const_iterator next2(next);
+ if (++next2 == bline.end())
+ {
+ if (loop) next2 =
bline.begin();
+ else next2 = next;
+ }
+
+ etl::hermite<Vector>
other_curve(next->get_vertex(), next2->get_vertex(), next->get_tangent2(),
next2->get_tangent1());
+ other_tangent =
other_curve(FAKE_TANGENT_STEP) - other_curve(0);
+ }
+
+ // normalise and sum the two tangents
+
tangent=(other_tangent.norm()+tangent.norm());
edge_case=true;
}
}
}
+ tangent = tangent.norm();
if(perpendicular)
{
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Synfig-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synfig-devl