Math.vala updated #3
This commit is contained in:
parent
3a57fdfde1
commit
348fae7605
|
@ -740,89 +740,19 @@ namespace CairoChart {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate int PointComparator(Point a, Point b);
|
|
||||||
void sort_points_delegate(Point[] points, PointComparator compare) {
|
|
||||||
for(var i = 0; i < points.length; ++i) {
|
|
||||||
for(var j = i + 1; j < points.length; ++j) {
|
|
||||||
if(compare(points[i], points[j]) > 0) {
|
|
||||||
var tmp = points[i];
|
|
||||||
points[i] = points[j];
|
|
||||||
points[j] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual bool cut_line (Point a, Point b, out Point c, out Point d) {
|
|
||||||
int ncross = 0;
|
|
||||||
Float128 x = 0, y = 0;
|
|
||||||
Point pc[4];
|
|
||||||
if (math.hcross(a, b, plot_x_min, plot_x_max, plot_y_min, out x))
|
|
||||||
pc[ncross++] = Point(x, plot_y_min);
|
|
||||||
if (math.hcross(a, b, plot_x_min, plot_x_max, plot_y_max, out x))
|
|
||||||
pc[ncross++] = Point(x, plot_y_max);
|
|
||||||
if (math.vcross(a, b, plot_x_min, plot_y_min, plot_y_max, out y))
|
|
||||||
pc[ncross++] = Point(plot_x_min, y);
|
|
||||||
if (math.vcross(a, b, plot_x_max, plot_y_min, plot_y_max, out y))
|
|
||||||
pc[ncross++] = Point(plot_x_max, y);
|
|
||||||
c = a;
|
|
||||||
d = b;
|
|
||||||
if (ncross == 0) {
|
|
||||||
if (point_in_plot_area (a) && point_in_plot_area (b))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (ncross >= 2) {
|
|
||||||
c = pc[0]; d = pc[1];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ncross == 1) {
|
|
||||||
if (point_in_plot_area (a)) {
|
|
||||||
c = a;
|
|
||||||
d = pc[0];
|
|
||||||
return true;
|
|
||||||
} else if (point_in_plot_area (b)) {
|
|
||||||
c = b;
|
|
||||||
d = pc[0];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual Point[] sort_points (Series s, Series.Sort sort) {
|
|
||||||
var points = s.points;
|
|
||||||
switch(sort) {
|
|
||||||
case Series.Sort.BY_X:
|
|
||||||
sort_points_delegate(points, (a, b) => {
|
|
||||||
if (a.x < b.x) return -1;
|
|
||||||
if (a.x > b.x) return 1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case Series.Sort.BY_Y:
|
|
||||||
sort_points_delegate(points, (a, b) => {
|
|
||||||
if (a.y < b.y) return -1;
|
|
||||||
if (a.y > b.y) return 1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void draw_series () {
|
protected virtual void draw_series () {
|
||||||
for (var si = 0; si < series.length; ++si) {
|
for (var si = 0; si < series.length; ++si) {
|
||||||
var s = series[si];
|
var s = series[si];
|
||||||
if (!s.zoom_show) continue;
|
if (!s.zoom_show) continue;
|
||||||
if (s.points.length == 0) continue;
|
if (s.points.length == 0) continue;
|
||||||
var points = sort_points(s, s.sort);
|
var points = math.sort_points(s, s.sort);
|
||||||
s.line_style.set(this);
|
s.line_style.set(this);
|
||||||
// draw series line
|
// draw series line
|
||||||
for (int i = 1; i < points.length; ++i) {
|
for (int i = 1; i < points.length; ++i) {
|
||||||
Point c, d;
|
Point c, d;
|
||||||
if (cut_line (Point(get_scr_x(s, points[i - 1].x), get_scr_y(s, points[i - 1].y)),
|
if (math.cut_line (Point(plot_x_min, plot_y_min), Point(plot_x_max, plot_y_max),
|
||||||
Point(get_scr_x(s, points[i].x), get_scr_y(s, points[i].y)),
|
Point(get_scr_x(s, points[i - 1].x), get_scr_y(s, points[i - 1].y)),
|
||||||
|
Point(get_scr_x(s, points[i].x), get_scr_y(s, points[i].y)),
|
||||||
out c, out d)) {
|
out c, out d)) {
|
||||||
context.move_to (c.x, c.y);
|
context.move_to (c.x, c.y);
|
||||||
context.line_to (d.x, d.y);
|
context.line_to (d.x, d.y);
|
||||||
|
@ -949,10 +879,10 @@ namespace CairoChart {
|
||||||
Point[] points = {};
|
Point[] points = {};
|
||||||
switch (cursor_style.orientation) {
|
switch (cursor_style.orientation) {
|
||||||
case Cursor.Orientation.VERTICAL:
|
case Cursor.Orientation.VERTICAL:
|
||||||
points = sort_points (s, s.sort);
|
points = math.sort_points (s, s.sort);
|
||||||
break;
|
break;
|
||||||
case Cursor.Orientation.HORIZONTAL:
|
case Cursor.Orientation.HORIZONTAL:
|
||||||
points = sort_points (s, s.sort);
|
points = math.sort_points (s, s.sort);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,79 @@ namespace CairoChart {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delegate int PointComparator(Point a, Point b);
|
||||||
|
|
||||||
|
public virtual void sort_points_delegate(Point[] points, PointComparator compare) {
|
||||||
|
for(var i = 0; i < points.length; ++i) {
|
||||||
|
for(var j = i + 1; j < points.length; ++j) {
|
||||||
|
if(compare(points[i], points[j]) > 0) {
|
||||||
|
var tmp = points[i];
|
||||||
|
points[i] = points[j];
|
||||||
|
points[j] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool cut_line (Point p_min, Point p_max, Point a, Point b, out Point c, out Point d) {
|
||||||
|
int ncross = 0;
|
||||||
|
Float128 x = 0, y = 0;
|
||||||
|
Point pc[4];
|
||||||
|
if (hcross(a, b, p_min.x, p_max.x, p_min.y, out x))
|
||||||
|
pc[ncross++] = Point(x, p_min.y);
|
||||||
|
if (hcross(a, b, p_min.x, p_max.x, p_max.y, out x))
|
||||||
|
pc[ncross++] = Point(x, p_max.y);
|
||||||
|
if (vcross(a, b, p_min.x, p_min.y, p_max.y, out y))
|
||||||
|
pc[ncross++] = Point(p_min.x, y);
|
||||||
|
if (vcross(a, b, p_max.x, p_min.y, p_max.y, out y))
|
||||||
|
pc[ncross++] = Point(p_max.x, y);
|
||||||
|
c = a;
|
||||||
|
d = b;
|
||||||
|
if (ncross == 0) {
|
||||||
|
if ( point_in_rect (a, p_min.x, p_max.x, p_min.y, p_max.y)
|
||||||
|
&& point_in_rect (b, p_min.x, p_max.x, p_min.y, p_max.y))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ncross >= 2) {
|
||||||
|
c = pc[0]; d = pc[1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ncross == 1) {
|
||||||
|
if (point_in_rect (a, p_min.x, p_max.x, p_min.y, p_max.y)) {
|
||||||
|
c = a;
|
||||||
|
d = pc[0];
|
||||||
|
return true;
|
||||||
|
} else if (point_in_rect (b, p_min.x, p_max.x, p_min.y, p_max.y)) {
|
||||||
|
c = b;
|
||||||
|
d = pc[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Point[] sort_points (Series s, Series.Sort sort) {
|
||||||
|
var points = s.points;
|
||||||
|
switch(sort) {
|
||||||
|
case Series.Sort.BY_X:
|
||||||
|
sort_points_delegate(points, (a, b) => {
|
||||||
|
if (a.x < b.x) return -1;
|
||||||
|
if (a.x > b.x) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case Series.Sort.BY_Y:
|
||||||
|
sort_points_delegate(points, (a, b) => {
|
||||||
|
if (a.y < b.y) return -1;
|
||||||
|
if (a.y > b.y) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Math () {}
|
public Math () {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue