找回密码
 欢迎注册
查看: 42451|回复: 15

[讨论] 关于多值隐函数绘图问题

[复制链接]
发表于 2011-1-13 15:05:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
有关于多值隐函数绘图的问题向大家请教! 以这个函数为例(x取-8~8,y取-8~8):f(x,y)=(x^2+y^2)^3-36*(x^2-y^2)^2; 可以求得x为任意值时对应的多个y值。绘图时,将每一组值(x,y)绘制为一个点,点数多了就会形成曲线,如下图: plotexample12.jpg 但如何将相邻的两个点连成线呢?就是说如何判断两个点是相邻的呢? 例如,以下代码求得了x=1.1及x=1.2时对应的y值;x=1.1的y值有6个,x=1.2的y值也有6个,如何判断哪些点该连成线呢?
  1. !using("fcopt");
  2. f(x,y)=(x^2+y^2)^3-36*(x^2-y^2)^2;
  3. isolve[HFor("f"), optrange,-8,8, optthis,1, optpara,1.1];
  4. isolve[HFor("f"), optrange,-8,8, optthis,1, optpara,1.2];
复制代码
1.1 -5.413569621185505 0. 1.1 -1.52029233271966 0. 1.1 -0.8671650244626143 8.881784197001252e-016 1.1 0.8671650244626143 8.881784197001252e-016 1.1 1.52029233271966 0. 1.1 5.413569621185504 0. 6. 1.2 -5.274704716901752 0. 1.2 -1.731609595222745 0. 1.2 -0.9268324331975657 0. 1.2 0.9268324331975657 0. 1.2 1.731609595222745 0. 1.2 5.274704716901752 0. 6.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2011-1-13 16:40:58 | 显示全部楼层
1# forcal 点画多了,越稠密,就越连续了, ================ 或者求出一定数目的点,然后线性插值,样条插值,...............
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2011-1-13 17:08:46 | 显示全部楼层
不知道你具体是在问什么 是关于画图引擎的渲染技巧吗 还是就题论题,只是画出该函数的 点图,然后标记一条直线? =================================== 前者,你可以参考gnuplot 如果是后者,你可以把方程化成极坐标的形式,就清晰了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2011-1-13 17:29:49 | 显示全部楼层
不知道你具体是在问什么 是关于画图引擎的渲染技巧吗 还是就题论题,只是画出该函数的 点图,然后标记一条直线? =================================== 前者,你可以参考gnuplot 如果是后者,你可以把方程化成极 ... wayne 发表于 2011-1-13 17:08
画出函数的点图是比较容易的,我想把点连成一条折线(曲线)。 例如matlab等画这个图的曲线是连续的,但并不是点图。 ========= 有些隐函数方程化成极坐标的形式是比较困难的。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2011-1-13 18:56:08 | 显示全部楼层
本帖最后由 wayne 于 2011-1-13 18:58 编辑 4# forcal
例如matlab等画这个图的曲线是连续的,但并不是点图。
那你做一个测试,试试: 先产生一个点序列,100个 ,,比如 {x,sin(x)} 然后shuffle一下,把这100对的顺序全部搞乱,越乱越好,再plot一下,看看,..................
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2011-1-13 19:10:21 | 显示全部楼层
4# forcal 如果你说的是contour plot, 那个实现起来要复杂一些, 你用google搜搜 contour plot Implementation 三天后我会回来的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2011-1-13 20:24:28 | 显示全部楼层
4# forcal 算了,再给你补一贴吧: 用OpenGL 画你给的那个函数: contourplot.png 代码:
  1. /* generates contours using marching squares */
  2. /* region size */
  3. #define X_MAX 8.0
  4. #define Y_MAX 8.0
  5. #define X_MIN -8.0
  6. #define Y_MIN -8.0
  7. /* number of cells */
  8. #define N_X 500
  9. #define N_Y 500
  10. /* contour value */
  11. #define THRESHOLD 0.0
  12. #include <GL/glut.h>
  13. void display()
  14. {
  15. double f(double,double);
  16. int cell(double, double, double, double);
  17. void lines(int, int, int, double, double, double, double);
  18. double data[N_X][N_Y];
  19. int i,j;
  20. int c;
  21. glClear(GL_COLOR_BUFFER_BIT);
  22. /* form data array from function */
  23. for(i=0;i<N_X;i++) for (j=0;j<N_Y;j++)
  24. data[i][j]=f(X_MIN+i*(X_MAX-(X_MIN))/(N_X-1.0), Y_MIN+j*(Y_MAX-(Y_MIN))/(N_Y-1.0));
  25. /* process each cell */
  26. for(i=0;i<N_X;i++) for (j=0;j<N_Y;j++)
  27. {
  28. c=cell(data[i][j], data[i+1][j], data[i+1][j+1], data[i][j+1]);
  29. lines(c,i,j,data[i][j], data[i+1][j], data[i+1][j+1], data[i][j+1]);
  30. }
  31. glFlush();
  32. }
  33. /* define function f(x,y) */
  34. double f(double x, double y)
  35. {
  36. double a=36;
  37. /* Ovals of Cassini */
  38. return (x*x+y*y)*(x*x+y*y)*(x*x+y*y)-a*(x*x-y*y)*(x*x-y*y);
  39. }
  40. /* define cell vertices */
  41. int cell(double a, double b, double c , double d)
  42. {
  43. int n=0;
  44. if(a>THRESHOLD) n+=1;
  45. if(b>THRESHOLD) n+=8;
  46. if(c>THRESHOLD) n+=4;
  47. if(d>THRESHOLD) n+=2;
  48. return n;
  49. }
  50. /* draw line segments for each case */
  51. void lines(int num, int i, int j, double a, double b, double c, double d)
  52. {
  53. void draw_one(int, int, int, double, double, double, double);
  54. void draw_adjacent(int, int, int, double, double, double, double);
  55. void draw_opposite(int, int, int, double, double, double, double);
  56. switch(num)
  57. {
  58. case 1: case 2: case 4: case 7: case 8: case 11: case 13: case 14:
  59. draw_one(num, i,j,a,b,c,d);
  60. break;
  61. case 3: case 6: case 9: case 12:
  62. draw_adjacent(num,i,j,a,b,c,d);
  63. break;
  64. case 5: case 10:
  65. draw_opposite(num, i,j,a,b,c,d);
  66. break;
  67. case 0: case 15: break;
  68. }
  69. }
  70. void draw_one(int num, int i, int j, double a, double b, double c, double d)
  71. {
  72. double x1, y1, x2, y2;
  73. double ox, oy;
  74. double dx, dy;
  75. dx=(X_MAX-(X_MIN))/(N_X-1.0);
  76. dy=(Y_MAX-(Y_MIN))/(N_Y-1.0);
  77. ox=X_MIN+i*(X_MAX-(X_MIN))/(N_X-1.0);
  78. oy=Y_MIN+j*(Y_MAX-(Y_MIN))/(N_Y-1.0);
  79. switch(num)
  80. {
  81. case 1: case 14:
  82. x1=ox;
  83. y1=oy+dy*(THRESHOLD-a)/(d-a);
  84. x2=ox+dx*(THRESHOLD-a)/(b-a);
  85. y2=oy;
  86. break;
  87. case 2: case 13:
  88. x1=ox;
  89. y1=oy+dy*(THRESHOLD-a)/(d-a);
  90. x2=ox+dx*(THRESHOLD-d)/(c-d);
  91. y2=oy+dy;
  92. break;
  93. case 4: case 11:
  94. x1=ox+dx*(THRESHOLD-d)/(c-d);
  95. y1=oy+dy;
  96. x2=ox+dx;
  97. y2=oy+dy*(THRESHOLD-b)/(c-b);
  98. break;
  99. case 7: case 8:
  100. x1=ox+dx*(THRESHOLD-a)/(b-a);
  101. y1=oy;
  102. x2=ox+dx;
  103. y2=oy+dy*(THRESHOLD-b)/(c-b);
  104. break;
  105. }
  106. glBegin(GL_LINES);
  107. glVertex2d(x1, y1);
  108. glVertex2d(x2, y2);
  109. glEnd();
  110. }
  111. void draw_adjacent(int num, int i, int j, double a, double b,
  112. double c, double d)
  113. {
  114. double x1, y1, x2, y2;
  115. double ox, oy;
  116. double dx, dy;
  117. dx=(X_MAX-(X_MIN))/(N_X-1.0);
  118. dy=(Y_MAX-(Y_MIN))/(N_Y-1.0);
  119. ox=X_MIN+i*(X_MAX-(X_MIN))/(N_X-1.0);
  120. oy=Y_MIN+j*(Y_MAX-(Y_MIN))/(N_Y-1.0);
  121. switch(num)
  122. {
  123. case 3: case 12:
  124. x1=ox+dx*(THRESHOLD-a)/(b-a);
  125. y1=oy;
  126. x2=ox+dx*(THRESHOLD-d)/(c-d);
  127. y2=oy+dy;
  128. break;
  129. case 6: case 9:
  130. x1=ox;
  131. y1=oy+dy*(THRESHOLD-a)/(d-a);
  132. x2=ox+dx;
  133. y2=oy+dy*(THRESHOLD-b)/(c-b);
  134. break;
  135. }
  136. glBegin(GL_LINES);
  137. glVertex2d(x1, y1);
  138. glVertex2d(x2, y2);
  139. glEnd();
  140. }
  141. void draw_opposite(int num, int i, int j, double a, double b,
  142. double c, double d)
  143. {
  144. double x1,y1,x2,y2,x3,y3,x4,y4;
  145. double ox, oy;
  146. double dx, dy;
  147. dx=(X_MAX-(X_MIN))/(N_X-1.0);
  148. dy=(Y_MAX-(Y_MIN))/(N_Y-1.0);
  149. ox=X_MIN+i*(X_MAX-(X_MIN))/(N_X-1.0);
  150. oy=Y_MIN+j*(Y_MAX-(Y_MIN))/(N_Y-1.0);
  151. switch(num)
  152. {
  153. case5:
  154. x1=ox;
  155. y1=oy+dy*(THRESHOLD-a)/(d-a);
  156. x2=ox+dx*(THRESHOLD-a)/(b-a);
  157. y2=oy;
  158. x3=ox+dx*(THRESHOLD-d)/(c-d);
  159. y3=oy+dy;
  160. x4=ox+dx;
  161. y4=oy+dy*(THRESHOLD-b)/(c-b);
  162. break;
  163. case 10:
  164. x1=ox;
  165. y1=oy+dy*(THRESHOLD-a)/(d-a);
  166. x2=ox+dx*(THRESHOLD-d)/(c-d);
  167. y2=oy+dy;
  168. x3=ox+dy*(THRESHOLD-a)/(b-a);
  169. y3=oy;
  170. x4=ox+dx;
  171. y4=oy+dy*(THRESHOLD-b)/(c-b);
  172. break;
  173. }
  174. glBegin(GL_LINES);
  175. glVertex2d(x1, y1);
  176. glVertex2d(x2, y2);
  177. glVertex2d(x3, y3);
  178. glVertex2d(x4, y4);
  179. glEnd();
  180. }
  181. void myReshape(int w, int h)
  182. {
  183. glViewport(0, 0, w, h);
  184. glMatrixMode(GL_PROJECTION);
  185. glLoadIdentity();
  186. if (w <= h) gluOrtho2D(X_MIN, X_MAX, Y_MIN * (GLfloat) h / (GLfloat) w, Y_MAX* (GLfloat) h / (GLfloat) w);
  187. else gluOrtho2D(X_MIN * (GLfloat) w / (GLfloat) h, X_MAX * (GLfloat) w / (GLfloat) h, Y_MIN, Y_MAX);
  188. glMatrixMode(GL_MODELVIEW);
  189. }
  190. int main(int argc, char **argv)
  191. {
  192. glutInit(&argc, argv);
  193. glutInitWindowSize(500, 500);
  194. glutCreateWindow("contour plot");
  195. glutReshapeFunc(myReshape);
  196. glutDisplayFunc(display);
  197. glClearColor(0.0,0.0,0.0,1.0);
  198. glColor3f(1.0,1.0,1.0);
  199. glutMainLoop();
  200. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2011-1-13 20:24:43 | 显示全部楼层
4# forcal 那你做一个测试,试试: 先产生一个点序列,100个 ,,比如 {x,sin(x)} 然后shuffle一下,把这100对的顺序全部搞乱,越乱越好,再plot一下,看看,.................. wayne 发表于 2011-1-13 18:56
我的意思是MATLAB提供了一个ezplot函数绘制隐函数图形,似乎不是用描点方式绘图的,它是如何绘制的? 对于单值函数f(x)=... ...;绘制曲线图是很容易的,将所有点按x的次序连起来即可。 但对于隐函数f(x,y)=0,一个x对应多个y值,该如何绘制曲线图?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2011-1-13 20:26:10 | 显示全部楼层
4# forcal 如果你说的是contour plot, 那个实现起来要复杂一些, 你用google搜搜 contour plot Implementation 三天后我会回来的 wayne 发表于 2011-1-13 19:10
英文不是很好,等你回来,呵呵。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2011-1-13 20:54:05 | 显示全部楼层
4# forcal 算了,再给你补一贴吧: 用OpenGL 画你给的那个函数: wayne 发表于 2011-1-13 20:24
这个绘图原理与我所说的不一样,我原想先解出所有要绘制的点,然后连成线,看来比较复杂。 这个OpenGL 绘隐函数图原理能大致说一下吗?看不太懂。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-12-26 19:25 , Processed in 0.030450 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表