genius r731 - in trunk: . src



Author: jirka
Date: Sun Feb 22 06:00:15 2009
New Revision: 731
URL: http://svn.gnome.org/viewvc/genius?rev=731&view=rev

Log:

Sun Feb 22 00:00:04 2009  Jiri (George) Lebl <jirka 5z com>

	* src/graphing.c: clip slopefield solutions to within the plot window.
	  to avoid unsightly overshooting lines when step size is too large
	  (or when slope is too large)



Modified:
   trunk/ChangeLog
   trunk/src/graphing.c

Modified: trunk/src/graphing.c
==============================================================================
--- trunk/src/graphing.c	(original)
+++ trunk/src/graphing.c	Sun Feb 22 06:00:15 2009
@@ -2991,6 +2991,54 @@
 }
 
 static void
+clip_line_ends (double xx[], double yy[], int len)
+{
+	if G_UNLIKELY (len < 2)
+		return;
+
+	if (xx[0] < plotx1) {
+		double slope = (yy[1]-yy[0])/(xx[1]-xx[0]);
+		xx[0] = plotx1;
+		yy[0] = yy[1] - (xx[1]-plotx1) * slope;
+	}
+
+	if (yy[0] < ploty1) {
+		if G_LIKELY (/* sanity */(xx[1]-xx[0]) > 0) {
+			double slope = (yy[1]-yy[0])/(xx[1]-xx[0]);
+			xx[0] = (ploty1 -yy[1] + slope*xx[1]) / slope;
+			yy[0] = ploty1;
+		}
+	} else if (yy[0] > ploty2) {
+		if G_LIKELY (/* sanity */(xx[1]-xx[0]) > 0) {
+			double slope = (yy[1]-yy[0])/(xx[1]-xx[0]);
+			xx[0] = (ploty2 -yy[1] + slope*xx[1]) / slope;
+			yy[0] = ploty2;
+		}
+	}
+
+	if (xx[len-1] > plotx2) {
+		double slope = (yy[len-1]-yy[len-2])
+			/ (xx[len-1]-xx[len-2]);
+		xx[len-1] = plotx2;
+		yy[len-1] = yy[len-2] + (plotx2-xx[len-2]) * slope;
+	}
+
+	if (yy[len-1] < ploty1) {
+		if G_LIKELY (/* sanity */(xx[len-1]-xx[len-2]) > 0) {
+			double slope = (yy[len-1]-yy[len-2])/(xx[len-1]-xx[len-2]);
+			xx[len-1] = (ploty1 - yy[len-2] + slope*xx[len-2]) / slope;
+			yy[len-1] = ploty1;
+		}
+	} else if (yy[len-1] > ploty2) {
+		if G_LIKELY (/* sanity */(xx[len-1]-xx[len-2]) > 0) {
+			double slope = (yy[len-1]-yy[len-2])/(xx[len-1]-xx[len-2]);
+			xx[len-1] = (ploty2 - yy[len-2] + slope*xx[len-2]) / slope;
+			yy[len-1] = ploty2;
+		}
+	}
+}
+
+static void
 solution_destroyed (GtkWidget *plotdata, gpointer data)
 {
 	solutions_list = g_slist_remove (solutions_list, plotdata);
@@ -3017,7 +3065,7 @@
 	len1 = 0;
 	cx = x;
 	cy = y;
-	while (cx <= plotx2 && cy >= ploty1 && cy <= ploty2) {
+	while (cx < plotx2 && cy > ploty1 && cy < ploty2) {
 		double *pt;
 		gboolean ex = FALSE;
 		double k1, k2, k3, k4, sl;
@@ -3055,7 +3103,7 @@
 	len2 = 0;
 	cx = x;
 	cy = y;
-	while (cx >= plotx1 && cy >= ploty1 && cy <= ploty2) {
+	while (cx > plotx1 && cy > ploty1 && cy < ploty2) {
 		double *pt;
 		gboolean ex = FALSE;
 		double k1, k2, k3, k4, sl;
@@ -3125,6 +3173,9 @@
 	g_slist_free (points1);
 	g_slist_free (points2);
 
+	/* Adjust ends */
+	clip_line_ends (xx, yy, len);
+
 	data = draw_line (xx, yy, len, 2 /* thickness */, &color);
 	solutions_list = g_slist_prepend (solutions_list,
 					  data);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]