16 个解决方案
#1
SetViewportOrg设置新的视口原点,建立常见的直角坐标系,然后直接按坐标的比例用lineto把等值点连接起来就行了
#2
其实没有什么难的,就是先进行逻辑坐标系到设备坐标系的转换,然后用LINETO将每一个对应在视图上的点联系起来就可以了,关键是如何作出的曲线美观,而且支持存储,打印。希望以下的页面会给你一点帮助
http://www.vccode.com/file_show.php?id=2518
http://www.vccode.com/file_show.php?id=2518
#3
用lineto函数就行。
#4
1。根据等值点,建立泰森三角网
2。在三角网的各边上找出等值点
3。连接各等值点
4。平化处理等值线
5。打断等值线,输出等高值
2。在三角网的各边上找出等值点
3。连接各等值点
4。平化处理等值线
5。打断等值线,输出等高值
#5
搜索引擎
http://search.csdn.net/search.asp?key=%BB%AD%B5%C8%D6%B5%CF%DF&pre=&option=nmlres&result=normal&page=1&size=10&x=30&y=19
http://search.csdn.net/search.asp?key=%BB%AD%B5%C8%D6%B5%CF%DF&pre=&option=nmlres&result=normal&page=1&size=10&x=30&y=19
#6
楼上的能把“打断等值线,输出等高值”说的具体些吗?
我现在也在做有关等值线的问题,
是用网格法
我现在也在做有关等值线的问题,
是用网格法
#7
就是在曲线上找三点比较平坦的地方且长度大于输出字符的长度
将中间的点去掉,在剩下两点间输出字符串。
将中间的点去掉,在剩下两点间输出字符串。
#8
连线可以用贝叶斯曲线,,
至于画坐标,不是很难,如果不想坐标转换,可以好好计算设备坐标,
就可以拉!
至于画坐标,不是很难,如果不想坐标转换,可以好好计算设备坐标,
就可以拉!
#9
等值线的追踪算法,Surfer软件里有很多,把等值点追踪出来了,绘制是很简单的事情
IT_Fly(浅斟低唱) 大概是高手,向他学习吧
IT_Fly(浅斟低唱) 大概是高手,向他学习吧
#10
个人感觉之所以要建立泰森三角网,是所得数据(等值点)是不连续的
而因为现实世界是连续的,所以建立三角网以线性插值得方法模拟现实世界
个人的胡思乱想,不知是否正确,希望大家多多探讨。
学过很多国外人提供的算法,有时候回头想想这些算法到底隐含了什么原理,
为什么这样就能解决问题。学了这些算法就能不能自己提出新的算法?
疑惑中。。。。。。
而因为现实世界是连续的,所以建立三角网以线性插值得方法模拟现实世界
个人的胡思乱想,不知是否正确,希望大家多多探讨。
学过很多国外人提供的算法,有时候回头想想这些算法到底隐含了什么原理,
为什么这样就能解决问题。学了这些算法就能不能自己提出新的算法?
疑惑中。。。。。。
#11
学习,呵呵~~~~~~~~~~~~~~~~~~~~~~~!~!
#12
-----Sample Code Follows----------
/*
* If you want try using this, you probably would need to provide
* graph_set_point(), and graph_draw_line(), besides do things like
* initialize window systems and so on.
*
* Please see the code for a note about data format
*/
/* Definitions */
struct _array {
float *a_elements;
int a_rows;
int a_cols;
float *a_filler;
};
#define ELTS(a) (a->a_elements)
#define NOROWS(a) (a->a_rows)
#define NOCOLS(a) (a->a_cols)
#define NOELTS(a) (NOROWS(a) * NOCOLS(a))
#define COLUMN_VECTOR(a) (NOCOLS((a)) == 1)
#define ROW_VECTOR(a) (NOROWS((a)) == 1)
typedef struct _array *array;
typedef struct _graph *graph;
typedef struct _graph_port *graph_port;
struct _graph_port {
char *p_window; /* window system dependent private */
double p_xmin; /* object space min x-coordinate */
double p_xmax; /* object space max x-coordinate */
double p_ymin; /* object space min y-coordinate */
double p_ymax; /* object space max y-coordinate */
double p_xscale; /* this is just x-max - x-min */
double p_yscale; /* this is just y-max - y-min */
int p_xorigin; /* image space x-origin co-ordinate */
int p_yorigin; /* image space y-origin */
int p_width; /* image space width */
int p_height; /* image space height */
int p_realwidth; /* image space width */
int p_realheight; /* image space height */
int p_curx; /* where current point is in image */
int p_cury; /* y-coordinate of above */
int p_line_offset; /* line offset for labels */
int p_autoscale; /* in auto scaling on? */
int p_include_xzero; /* include x zero axis */
int p_include_yzero; /* include y zero axis */
int p_titlefont;
int p_ticfont;
int p_labelfont;
int p_margin;
int p_ticstyle; /* styles of tics (large, small or none) */
};
struct _graph {
int g_no; /* number associated with this graph */
int g_points; /* total number of points in graph */
array g_x; /* graph x points */
array g_y; /* graph y points */
array g_z; /* graph z points */
char *g_line_label; /* graph line label */
char *g_xlabel; /* graph x axis label */
char *g_ylabel; /* graph y axis label */
char *g_title; /* graph title */
int g_color; /* graph color or pattern */
int g_type; /* type of graph */
};
/*
* Contour Plotting algorithm!
*/
/*
* This routine does the level comparison.
* It takes three points, a level, and a color.
* It intersects the triangle with a plane at the given level,
* and draws the line segments that denote these intersections.
*/
#define swap_val(x, y, temp) {temp = x; x = y; y = x; }
static
graph_segment(gp, x1, y1, z1, x2, y2, z2, x3, y3, z3, level, color)
graph_port gp;
double x1, y1, z1, x2, y2, z2, x3, y3, z3, level;
int color;
{
double x, y, factor, temp;
if(z1 >= z2) {
swap_val(x1, x2, temp);
swap_val(y1, y2, temp);
swap_val(z1, z2, temp);
}
if(z2 > z3) {
if(z3 < z1) {
swap_val(x1, x3, temp);
swap_val(y1, y3, temp);
swap_val(z1, z3, temp);
}
swap_val(x2, x3, temp);
swap_val(y2, y3, temp);
swap_val(z2, z3, temp);
}
/* z1 <= z2 <= z3 */
if(level < z1 || level > z3) {
return;
}
if((level == z1) && (z1 == z2) && (z2 != z3)) {
/* draw a line from x1, y1 to x2, y2 */
graph_set_point(gp, x1, y1, color);
graph_lineto(gp, x2, y2, color);
return 1;
}
if((level == z3) && (z3 == z2) && (z1 != z2)) {
/* draw a line from x2, y2 to x3, y3 */
graph_set_point(gp, x2, y2, color);
graph_lineto(gp, x3, y3, color);
return 1;
}
if(level == z2) {
/* we know that z2 is definitely between z1 and z3
draw a line from P2 to point on segment between P1 and P3
*/
if(z3 == z1) return 0;
factor = (level - z1)/(z3-z1);
x = x1 + (x3-x1) * factor;
y = y1 + (y3-y1) * factor;
graph_set_point(gp, x2, y2, color);
graph_lineto(gp, x, y, color);
return 1;
}
if(level < z2) {
/* P2 and P3 are above, P1 below */
if(z2 == z1 || z3 == z1) return 0;
factor = (level - z1) / (z2 - z1);
x = x1 + (x2 - x1) * factor;
y = y1 + (y2 - y1) * factor;
graph_set_point(gp, x, y, color);
factor = (level - z1) / (z3 - z1);
x = x1 + (x3 - x1) * factor;
y = y1 + (y3 - y1) * factor;
graph_lineto(gp, x, y, color);
return 1;
} else {
/* P1 and P2 are below, P3 above */
if(z3 == z1 || z3 == z2) return 0;
factor = (level - z1) / (z3 - z1);
x = x1 + (x3 - x1) * factor;
y = y1 + (y3 - y1) * factor;
graph_set_point(gp, x, y, color);
factor = (level - z2) / (z3 - z2);
x = x2 + (x3 - x2) * factor;
y = y2 + (y3 - y2) * factor;
graph_lineto(gp, x, y, color);
return 1;
}
return 0;
}
/* This is the main function */
/* Data formats;
g->g_x -> contains N x values.
g->g_y -> contains N y values.
g->g_z -> contains N^2 z values, which are interpreted as a
matrix of z values, as
z[0][0], z[0][1] .... z[0][N],
z[1][0], ... upto z[N][N].
(horizontal sweep from X_min to X_max, inner loop
going from Y_min to Y_max);
This way we only store N^2+2N values instead of 3N^2 values.
*/
graph_plot_contour(gp, g, color)
graph_port gp;
graph g;
int color;
{
register int i, j;
float *x, *y, *z;
float minz, maxz;
double xavg, yavg, zavg;
double level, diff;
double zij, zipj, zijp, zipjp;
x = g->g_x->a_elements;
y = g->g_y->a_elements;
z = g->g_z->a_elements;
/*
* We find the min. and max values of the Z heights and divide that
* by a number of levels that is pre-determined.
* We should really do something more reasonable here, similar to the
* stuff we do for figuring out tick marks on 2-d plots
*/
array_minmax(g->g_z, &minz, &maxz);
diff = (maxz - minz)/10.0;
for(i=0;i<NOROWS(g->g_x)-1;i++) {
xavg = (x + x[i+1]) / 2.0;
for(j=0;j<NOROWS(g->g_y)-1;j++) {
yavg = (y[j] + y[j+1]) / 2.0;
zij = z[(i*NOROWS(g->g_y))+j];
zipj = z[((i+1)*NOROWS(g->g_y))+j];
zijp = z[(i*NOROWS(g->g_y))+j+1];
zipjp = z[((i+1)*NOROWS(g->g_y))+j+1];
zavg = (zij + zipj + zijp + zipjp)/4.0;
/* For each level */
for(level = minz; level < maxz; level += diff) {
/* Triangle i,j avg and i,j+1 */
graph_segment(gp, x, y[j], zij, x, y[j+1], zijp,
xavg, yavg, zavg, level, color);
graph_segment(gp, x, y[j], zij, x[i+1], y[j], zipj,
xavg, yavg, zavg, level, color);
graph_segment(gp, x[i+1], y[j], zipj, x[i+1], y[j+1], zipjp,
xavg, yavg, zavg, level, color);
graph_segment(gp, x, y[j+1], zijp, x[i+1], y[j+1], zipjp,
xavg, yavg, zavg, level, color);
}
}
}
}
/*
* If you want try using this, you probably would need to provide
* graph_set_point(), and graph_draw_line(), besides do things like
* initialize window systems and so on.
*
* Please see the code for a note about data format
*/
/* Definitions */
struct _array {
float *a_elements;
int a_rows;
int a_cols;
float *a_filler;
};
#define ELTS(a) (a->a_elements)
#define NOROWS(a) (a->a_rows)
#define NOCOLS(a) (a->a_cols)
#define NOELTS(a) (NOROWS(a) * NOCOLS(a))
#define COLUMN_VECTOR(a) (NOCOLS((a)) == 1)
#define ROW_VECTOR(a) (NOROWS((a)) == 1)
typedef struct _array *array;
typedef struct _graph *graph;
typedef struct _graph_port *graph_port;
struct _graph_port {
char *p_window; /* window system dependent private */
double p_xmin; /* object space min x-coordinate */
double p_xmax; /* object space max x-coordinate */
double p_ymin; /* object space min y-coordinate */
double p_ymax; /* object space max y-coordinate */
double p_xscale; /* this is just x-max - x-min */
double p_yscale; /* this is just y-max - y-min */
int p_xorigin; /* image space x-origin co-ordinate */
int p_yorigin; /* image space y-origin */
int p_width; /* image space width */
int p_height; /* image space height */
int p_realwidth; /* image space width */
int p_realheight; /* image space height */
int p_curx; /* where current point is in image */
int p_cury; /* y-coordinate of above */
int p_line_offset; /* line offset for labels */
int p_autoscale; /* in auto scaling on? */
int p_include_xzero; /* include x zero axis */
int p_include_yzero; /* include y zero axis */
int p_titlefont;
int p_ticfont;
int p_labelfont;
int p_margin;
int p_ticstyle; /* styles of tics (large, small or none) */
};
struct _graph {
int g_no; /* number associated with this graph */
int g_points; /* total number of points in graph */
array g_x; /* graph x points */
array g_y; /* graph y points */
array g_z; /* graph z points */
char *g_line_label; /* graph line label */
char *g_xlabel; /* graph x axis label */
char *g_ylabel; /* graph y axis label */
char *g_title; /* graph title */
int g_color; /* graph color or pattern */
int g_type; /* type of graph */
};
/*
* Contour Plotting algorithm!
*/
/*
* This routine does the level comparison.
* It takes three points, a level, and a color.
* It intersects the triangle with a plane at the given level,
* and draws the line segments that denote these intersections.
*/
#define swap_val(x, y, temp) {temp = x; x = y; y = x; }
static
graph_segment(gp, x1, y1, z1, x2, y2, z2, x3, y3, z3, level, color)
graph_port gp;
double x1, y1, z1, x2, y2, z2, x3, y3, z3, level;
int color;
{
double x, y, factor, temp;
if(z1 >= z2) {
swap_val(x1, x2, temp);
swap_val(y1, y2, temp);
swap_val(z1, z2, temp);
}
if(z2 > z3) {
if(z3 < z1) {
swap_val(x1, x3, temp);
swap_val(y1, y3, temp);
swap_val(z1, z3, temp);
}
swap_val(x2, x3, temp);
swap_val(y2, y3, temp);
swap_val(z2, z3, temp);
}
/* z1 <= z2 <= z3 */
if(level < z1 || level > z3) {
return;
}
if((level == z1) && (z1 == z2) && (z2 != z3)) {
/* draw a line from x1, y1 to x2, y2 */
graph_set_point(gp, x1, y1, color);
graph_lineto(gp, x2, y2, color);
return 1;
}
if((level == z3) && (z3 == z2) && (z1 != z2)) {
/* draw a line from x2, y2 to x3, y3 */
graph_set_point(gp, x2, y2, color);
graph_lineto(gp, x3, y3, color);
return 1;
}
if(level == z2) {
/* we know that z2 is definitely between z1 and z3
draw a line from P2 to point on segment between P1 and P3
*/
if(z3 == z1) return 0;
factor = (level - z1)/(z3-z1);
x = x1 + (x3-x1) * factor;
y = y1 + (y3-y1) * factor;
graph_set_point(gp, x2, y2, color);
graph_lineto(gp, x, y, color);
return 1;
}
if(level < z2) {
/* P2 and P3 are above, P1 below */
if(z2 == z1 || z3 == z1) return 0;
factor = (level - z1) / (z2 - z1);
x = x1 + (x2 - x1) * factor;
y = y1 + (y2 - y1) * factor;
graph_set_point(gp, x, y, color);
factor = (level - z1) / (z3 - z1);
x = x1 + (x3 - x1) * factor;
y = y1 + (y3 - y1) * factor;
graph_lineto(gp, x, y, color);
return 1;
} else {
/* P1 and P2 are below, P3 above */
if(z3 == z1 || z3 == z2) return 0;
factor = (level - z1) / (z3 - z1);
x = x1 + (x3 - x1) * factor;
y = y1 + (y3 - y1) * factor;
graph_set_point(gp, x, y, color);
factor = (level - z2) / (z3 - z2);
x = x2 + (x3 - x2) * factor;
y = y2 + (y3 - y2) * factor;
graph_lineto(gp, x, y, color);
return 1;
}
return 0;
}
/* This is the main function */
/* Data formats;
g->g_x -> contains N x values.
g->g_y -> contains N y values.
g->g_z -> contains N^2 z values, which are interpreted as a
matrix of z values, as
z[0][0], z[0][1] .... z[0][N],
z[1][0], ... upto z[N][N].
(horizontal sweep from X_min to X_max, inner loop
going from Y_min to Y_max);
This way we only store N^2+2N values instead of 3N^2 values.
*/
graph_plot_contour(gp, g, color)
graph_port gp;
graph g;
int color;
{
register int i, j;
float *x, *y, *z;
float minz, maxz;
double xavg, yavg, zavg;
double level, diff;
double zij, zipj, zijp, zipjp;
x = g->g_x->a_elements;
y = g->g_y->a_elements;
z = g->g_z->a_elements;
/*
* We find the min. and max values of the Z heights and divide that
* by a number of levels that is pre-determined.
* We should really do something more reasonable here, similar to the
* stuff we do for figuring out tick marks on 2-d plots
*/
array_minmax(g->g_z, &minz, &maxz);
diff = (maxz - minz)/10.0;
for(i=0;i<NOROWS(g->g_x)-1;i++) {
xavg = (x + x[i+1]) / 2.0;
for(j=0;j<NOROWS(g->g_y)-1;j++) {
yavg = (y[j] + y[j+1]) / 2.0;
zij = z[(i*NOROWS(g->g_y))+j];
zipj = z[((i+1)*NOROWS(g->g_y))+j];
zijp = z[(i*NOROWS(g->g_y))+j+1];
zipjp = z[((i+1)*NOROWS(g->g_y))+j+1];
zavg = (zij + zipj + zijp + zipjp)/4.0;
/* For each level */
for(level = minz; level < maxz; level += diff) {
/* Triangle i,j avg and i,j+1 */
graph_segment(gp, x, y[j], zij, x, y[j+1], zijp,
xavg, yavg, zavg, level, color);
graph_segment(gp, x, y[j], zij, x[i+1], y[j], zipj,
xavg, yavg, zavg, level, color);
graph_segment(gp, x[i+1], y[j], zipj, x[i+1], y[j+1], zipjp,
xavg, yavg, zavg, level, color);
graph_segment(gp, x, y[j+1], zijp, x[i+1], y[j+1], zipjp,
xavg, yavg, zavg, level, color);
}
}
}
}
#13
#14
关注,
#15
#16
我有三角网生长法的Delaunay剖分的程序和网格化绘等值线的程序,有兴趣的朋友可以加我:21154192
邮箱:dsgsos@163.com
希望大家共同提高。另外本人研究断层等值线绘制与实现,对各种有关等值线算法有所了解欢迎探讨。
邮箱:dsgsos@163.com
希望大家共同提高。另外本人研究断层等值线绘制与实现,对各种有关等值线算法有所了解欢迎探讨。
#1
SetViewportOrg设置新的视口原点,建立常见的直角坐标系,然后直接按坐标的比例用lineto把等值点连接起来就行了
#2
其实没有什么难的,就是先进行逻辑坐标系到设备坐标系的转换,然后用LINETO将每一个对应在视图上的点联系起来就可以了,关键是如何作出的曲线美观,而且支持存储,打印。希望以下的页面会给你一点帮助
http://www.vccode.com/file_show.php?id=2518
http://www.vccode.com/file_show.php?id=2518
#3
用lineto函数就行。
#4
1。根据等值点,建立泰森三角网
2。在三角网的各边上找出等值点
3。连接各等值点
4。平化处理等值线
5。打断等值线,输出等高值
2。在三角网的各边上找出等值点
3。连接各等值点
4。平化处理等值线
5。打断等值线,输出等高值
#5
搜索引擎
http://search.csdn.net/search.asp?key=%BB%AD%B5%C8%D6%B5%CF%DF&pre=&option=nmlres&result=normal&page=1&size=10&x=30&y=19
http://search.csdn.net/search.asp?key=%BB%AD%B5%C8%D6%B5%CF%DF&pre=&option=nmlres&result=normal&page=1&size=10&x=30&y=19
#6
楼上的能把“打断等值线,输出等高值”说的具体些吗?
我现在也在做有关等值线的问题,
是用网格法
我现在也在做有关等值线的问题,
是用网格法
#7
就是在曲线上找三点比较平坦的地方且长度大于输出字符的长度
将中间的点去掉,在剩下两点间输出字符串。
将中间的点去掉,在剩下两点间输出字符串。
#8
连线可以用贝叶斯曲线,,
至于画坐标,不是很难,如果不想坐标转换,可以好好计算设备坐标,
就可以拉!
至于画坐标,不是很难,如果不想坐标转换,可以好好计算设备坐标,
就可以拉!
#9
等值线的追踪算法,Surfer软件里有很多,把等值点追踪出来了,绘制是很简单的事情
IT_Fly(浅斟低唱) 大概是高手,向他学习吧
IT_Fly(浅斟低唱) 大概是高手,向他学习吧
#10
个人感觉之所以要建立泰森三角网,是所得数据(等值点)是不连续的
而因为现实世界是连续的,所以建立三角网以线性插值得方法模拟现实世界
个人的胡思乱想,不知是否正确,希望大家多多探讨。
学过很多国外人提供的算法,有时候回头想想这些算法到底隐含了什么原理,
为什么这样就能解决问题。学了这些算法就能不能自己提出新的算法?
疑惑中。。。。。。
而因为现实世界是连续的,所以建立三角网以线性插值得方法模拟现实世界
个人的胡思乱想,不知是否正确,希望大家多多探讨。
学过很多国外人提供的算法,有时候回头想想这些算法到底隐含了什么原理,
为什么这样就能解决问题。学了这些算法就能不能自己提出新的算法?
疑惑中。。。。。。
#11
学习,呵呵~~~~~~~~~~~~~~~~~~~~~~~!~!
#12
-----Sample Code Follows----------
/*
* If you want try using this, you probably would need to provide
* graph_set_point(), and graph_draw_line(), besides do things like
* initialize window systems and so on.
*
* Please see the code for a note about data format
*/
/* Definitions */
struct _array {
float *a_elements;
int a_rows;
int a_cols;
float *a_filler;
};
#define ELTS(a) (a->a_elements)
#define NOROWS(a) (a->a_rows)
#define NOCOLS(a) (a->a_cols)
#define NOELTS(a) (NOROWS(a) * NOCOLS(a))
#define COLUMN_VECTOR(a) (NOCOLS((a)) == 1)
#define ROW_VECTOR(a) (NOROWS((a)) == 1)
typedef struct _array *array;
typedef struct _graph *graph;
typedef struct _graph_port *graph_port;
struct _graph_port {
char *p_window; /* window system dependent private */
double p_xmin; /* object space min x-coordinate */
double p_xmax; /* object space max x-coordinate */
double p_ymin; /* object space min y-coordinate */
double p_ymax; /* object space max y-coordinate */
double p_xscale; /* this is just x-max - x-min */
double p_yscale; /* this is just y-max - y-min */
int p_xorigin; /* image space x-origin co-ordinate */
int p_yorigin; /* image space y-origin */
int p_width; /* image space width */
int p_height; /* image space height */
int p_realwidth; /* image space width */
int p_realheight; /* image space height */
int p_curx; /* where current point is in image */
int p_cury; /* y-coordinate of above */
int p_line_offset; /* line offset for labels */
int p_autoscale; /* in auto scaling on? */
int p_include_xzero; /* include x zero axis */
int p_include_yzero; /* include y zero axis */
int p_titlefont;
int p_ticfont;
int p_labelfont;
int p_margin;
int p_ticstyle; /* styles of tics (large, small or none) */
};
struct _graph {
int g_no; /* number associated with this graph */
int g_points; /* total number of points in graph */
array g_x; /* graph x points */
array g_y; /* graph y points */
array g_z; /* graph z points */
char *g_line_label; /* graph line label */
char *g_xlabel; /* graph x axis label */
char *g_ylabel; /* graph y axis label */
char *g_title; /* graph title */
int g_color; /* graph color or pattern */
int g_type; /* type of graph */
};
/*
* Contour Plotting algorithm!
*/
/*
* This routine does the level comparison.
* It takes three points, a level, and a color.
* It intersects the triangle with a plane at the given level,
* and draws the line segments that denote these intersections.
*/
#define swap_val(x, y, temp) {temp = x; x = y; y = x; }
static
graph_segment(gp, x1, y1, z1, x2, y2, z2, x3, y3, z3, level, color)
graph_port gp;
double x1, y1, z1, x2, y2, z2, x3, y3, z3, level;
int color;
{
double x, y, factor, temp;
if(z1 >= z2) {
swap_val(x1, x2, temp);
swap_val(y1, y2, temp);
swap_val(z1, z2, temp);
}
if(z2 > z3) {
if(z3 < z1) {
swap_val(x1, x3, temp);
swap_val(y1, y3, temp);
swap_val(z1, z3, temp);
}
swap_val(x2, x3, temp);
swap_val(y2, y3, temp);
swap_val(z2, z3, temp);
}
/* z1 <= z2 <= z3 */
if(level < z1 || level > z3) {
return;
}
if((level == z1) && (z1 == z2) && (z2 != z3)) {
/* draw a line from x1, y1 to x2, y2 */
graph_set_point(gp, x1, y1, color);
graph_lineto(gp, x2, y2, color);
return 1;
}
if((level == z3) && (z3 == z2) && (z1 != z2)) {
/* draw a line from x2, y2 to x3, y3 */
graph_set_point(gp, x2, y2, color);
graph_lineto(gp, x3, y3, color);
return 1;
}
if(level == z2) {
/* we know that z2 is definitely between z1 and z3
draw a line from P2 to point on segment between P1 and P3
*/
if(z3 == z1) return 0;
factor = (level - z1)/(z3-z1);
x = x1 + (x3-x1) * factor;
y = y1 + (y3-y1) * factor;
graph_set_point(gp, x2, y2, color);
graph_lineto(gp, x, y, color);
return 1;
}
if(level < z2) {
/* P2 and P3 are above, P1 below */
if(z2 == z1 || z3 == z1) return 0;
factor = (level - z1) / (z2 - z1);
x = x1 + (x2 - x1) * factor;
y = y1 + (y2 - y1) * factor;
graph_set_point(gp, x, y, color);
factor = (level - z1) / (z3 - z1);
x = x1 + (x3 - x1) * factor;
y = y1 + (y3 - y1) * factor;
graph_lineto(gp, x, y, color);
return 1;
} else {
/* P1 and P2 are below, P3 above */
if(z3 == z1 || z3 == z2) return 0;
factor = (level - z1) / (z3 - z1);
x = x1 + (x3 - x1) * factor;
y = y1 + (y3 - y1) * factor;
graph_set_point(gp, x, y, color);
factor = (level - z2) / (z3 - z2);
x = x2 + (x3 - x2) * factor;
y = y2 + (y3 - y2) * factor;
graph_lineto(gp, x, y, color);
return 1;
}
return 0;
}
/* This is the main function */
/* Data formats;
g->g_x -> contains N x values.
g->g_y -> contains N y values.
g->g_z -> contains N^2 z values, which are interpreted as a
matrix of z values, as
z[0][0], z[0][1] .... z[0][N],
z[1][0], ... upto z[N][N].
(horizontal sweep from X_min to X_max, inner loop
going from Y_min to Y_max);
This way we only store N^2+2N values instead of 3N^2 values.
*/
graph_plot_contour(gp, g, color)
graph_port gp;
graph g;
int color;
{
register int i, j;
float *x, *y, *z;
float minz, maxz;
double xavg, yavg, zavg;
double level, diff;
double zij, zipj, zijp, zipjp;
x = g->g_x->a_elements;
y = g->g_y->a_elements;
z = g->g_z->a_elements;
/*
* We find the min. and max values of the Z heights and divide that
* by a number of levels that is pre-determined.
* We should really do something more reasonable here, similar to the
* stuff we do for figuring out tick marks on 2-d plots
*/
array_minmax(g->g_z, &minz, &maxz);
diff = (maxz - minz)/10.0;
for(i=0;i<NOROWS(g->g_x)-1;i++) {
xavg = (x + x[i+1]) / 2.0;
for(j=0;j<NOROWS(g->g_y)-1;j++) {
yavg = (y[j] + y[j+1]) / 2.0;
zij = z[(i*NOROWS(g->g_y))+j];
zipj = z[((i+1)*NOROWS(g->g_y))+j];
zijp = z[(i*NOROWS(g->g_y))+j+1];
zipjp = z[((i+1)*NOROWS(g->g_y))+j+1];
zavg = (zij + zipj + zijp + zipjp)/4.0;
/* For each level */
for(level = minz; level < maxz; level += diff) {
/* Triangle i,j avg and i,j+1 */
graph_segment(gp, x, y[j], zij, x, y[j+1], zijp,
xavg, yavg, zavg, level, color);
graph_segment(gp, x, y[j], zij, x[i+1], y[j], zipj,
xavg, yavg, zavg, level, color);
graph_segment(gp, x[i+1], y[j], zipj, x[i+1], y[j+1], zipjp,
xavg, yavg, zavg, level, color);
graph_segment(gp, x, y[j+1], zijp, x[i+1], y[j+1], zipjp,
xavg, yavg, zavg, level, color);
}
}
}
}
/*
* If you want try using this, you probably would need to provide
* graph_set_point(), and graph_draw_line(), besides do things like
* initialize window systems and so on.
*
* Please see the code for a note about data format
*/
/* Definitions */
struct _array {
float *a_elements;
int a_rows;
int a_cols;
float *a_filler;
};
#define ELTS(a) (a->a_elements)
#define NOROWS(a) (a->a_rows)
#define NOCOLS(a) (a->a_cols)
#define NOELTS(a) (NOROWS(a) * NOCOLS(a))
#define COLUMN_VECTOR(a) (NOCOLS((a)) == 1)
#define ROW_VECTOR(a) (NOROWS((a)) == 1)
typedef struct _array *array;
typedef struct _graph *graph;
typedef struct _graph_port *graph_port;
struct _graph_port {
char *p_window; /* window system dependent private */
double p_xmin; /* object space min x-coordinate */
double p_xmax; /* object space max x-coordinate */
double p_ymin; /* object space min y-coordinate */
double p_ymax; /* object space max y-coordinate */
double p_xscale; /* this is just x-max - x-min */
double p_yscale; /* this is just y-max - y-min */
int p_xorigin; /* image space x-origin co-ordinate */
int p_yorigin; /* image space y-origin */
int p_width; /* image space width */
int p_height; /* image space height */
int p_realwidth; /* image space width */
int p_realheight; /* image space height */
int p_curx; /* where current point is in image */
int p_cury; /* y-coordinate of above */
int p_line_offset; /* line offset for labels */
int p_autoscale; /* in auto scaling on? */
int p_include_xzero; /* include x zero axis */
int p_include_yzero; /* include y zero axis */
int p_titlefont;
int p_ticfont;
int p_labelfont;
int p_margin;
int p_ticstyle; /* styles of tics (large, small or none) */
};
struct _graph {
int g_no; /* number associated with this graph */
int g_points; /* total number of points in graph */
array g_x; /* graph x points */
array g_y; /* graph y points */
array g_z; /* graph z points */
char *g_line_label; /* graph line label */
char *g_xlabel; /* graph x axis label */
char *g_ylabel; /* graph y axis label */
char *g_title; /* graph title */
int g_color; /* graph color or pattern */
int g_type; /* type of graph */
};
/*
* Contour Plotting algorithm!
*/
/*
* This routine does the level comparison.
* It takes three points, a level, and a color.
* It intersects the triangle with a plane at the given level,
* and draws the line segments that denote these intersections.
*/
#define swap_val(x, y, temp) {temp = x; x = y; y = x; }
static
graph_segment(gp, x1, y1, z1, x2, y2, z2, x3, y3, z3, level, color)
graph_port gp;
double x1, y1, z1, x2, y2, z2, x3, y3, z3, level;
int color;
{
double x, y, factor, temp;
if(z1 >= z2) {
swap_val(x1, x2, temp);
swap_val(y1, y2, temp);
swap_val(z1, z2, temp);
}
if(z2 > z3) {
if(z3 < z1) {
swap_val(x1, x3, temp);
swap_val(y1, y3, temp);
swap_val(z1, z3, temp);
}
swap_val(x2, x3, temp);
swap_val(y2, y3, temp);
swap_val(z2, z3, temp);
}
/* z1 <= z2 <= z3 */
if(level < z1 || level > z3) {
return;
}
if((level == z1) && (z1 == z2) && (z2 != z3)) {
/* draw a line from x1, y1 to x2, y2 */
graph_set_point(gp, x1, y1, color);
graph_lineto(gp, x2, y2, color);
return 1;
}
if((level == z3) && (z3 == z2) && (z1 != z2)) {
/* draw a line from x2, y2 to x3, y3 */
graph_set_point(gp, x2, y2, color);
graph_lineto(gp, x3, y3, color);
return 1;
}
if(level == z2) {
/* we know that z2 is definitely between z1 and z3
draw a line from P2 to point on segment between P1 and P3
*/
if(z3 == z1) return 0;
factor = (level - z1)/(z3-z1);
x = x1 + (x3-x1) * factor;
y = y1 + (y3-y1) * factor;
graph_set_point(gp, x2, y2, color);
graph_lineto(gp, x, y, color);
return 1;
}
if(level < z2) {
/* P2 and P3 are above, P1 below */
if(z2 == z1 || z3 == z1) return 0;
factor = (level - z1) / (z2 - z1);
x = x1 + (x2 - x1) * factor;
y = y1 + (y2 - y1) * factor;
graph_set_point(gp, x, y, color);
factor = (level - z1) / (z3 - z1);
x = x1 + (x3 - x1) * factor;
y = y1 + (y3 - y1) * factor;
graph_lineto(gp, x, y, color);
return 1;
} else {
/* P1 and P2 are below, P3 above */
if(z3 == z1 || z3 == z2) return 0;
factor = (level - z1) / (z3 - z1);
x = x1 + (x3 - x1) * factor;
y = y1 + (y3 - y1) * factor;
graph_set_point(gp, x, y, color);
factor = (level - z2) / (z3 - z2);
x = x2 + (x3 - x2) * factor;
y = y2 + (y3 - y2) * factor;
graph_lineto(gp, x, y, color);
return 1;
}
return 0;
}
/* This is the main function */
/* Data formats;
g->g_x -> contains N x values.
g->g_y -> contains N y values.
g->g_z -> contains N^2 z values, which are interpreted as a
matrix of z values, as
z[0][0], z[0][1] .... z[0][N],
z[1][0], ... upto z[N][N].
(horizontal sweep from X_min to X_max, inner loop
going from Y_min to Y_max);
This way we only store N^2+2N values instead of 3N^2 values.
*/
graph_plot_contour(gp, g, color)
graph_port gp;
graph g;
int color;
{
register int i, j;
float *x, *y, *z;
float minz, maxz;
double xavg, yavg, zavg;
double level, diff;
double zij, zipj, zijp, zipjp;
x = g->g_x->a_elements;
y = g->g_y->a_elements;
z = g->g_z->a_elements;
/*
* We find the min. and max values of the Z heights and divide that
* by a number of levels that is pre-determined.
* We should really do something more reasonable here, similar to the
* stuff we do for figuring out tick marks on 2-d plots
*/
array_minmax(g->g_z, &minz, &maxz);
diff = (maxz - minz)/10.0;
for(i=0;i<NOROWS(g->g_x)-1;i++) {
xavg = (x + x[i+1]) / 2.0;
for(j=0;j<NOROWS(g->g_y)-1;j++) {
yavg = (y[j] + y[j+1]) / 2.0;
zij = z[(i*NOROWS(g->g_y))+j];
zipj = z[((i+1)*NOROWS(g->g_y))+j];
zijp = z[(i*NOROWS(g->g_y))+j+1];
zipjp = z[((i+1)*NOROWS(g->g_y))+j+1];
zavg = (zij + zipj + zijp + zipjp)/4.0;
/* For each level */
for(level = minz; level < maxz; level += diff) {
/* Triangle i,j avg and i,j+1 */
graph_segment(gp, x, y[j], zij, x, y[j+1], zijp,
xavg, yavg, zavg, level, color);
graph_segment(gp, x, y[j], zij, x[i+1], y[j], zipj,
xavg, yavg, zavg, level, color);
graph_segment(gp, x[i+1], y[j], zipj, x[i+1], y[j+1], zipjp,
xavg, yavg, zavg, level, color);
graph_segment(gp, x, y[j+1], zijp, x[i+1], y[j+1], zipjp,
xavg, yavg, zavg, level, color);
}
}
}
}
#13
#14
关注,
#15
#16
我有三角网生长法的Delaunay剖分的程序和网格化绘等值线的程序,有兴趣的朋友可以加我:21154192
邮箱:dsgsos@163.com
希望大家共同提高。另外本人研究断层等值线绘制与实现,对各种有关等值线算法有所了解欢迎探讨。
邮箱:dsgsos@163.com
希望大家共同提高。另外本人研究断层等值线绘制与实现,对各种有关等值线算法有所了解欢迎探讨。