Chris_M_Thomasson

3d Power Stack For Owen

Nov 18th, 2019
542
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.18 KB | None | 0 0
  1. /*
  2. A Simple 2d Plane For Owen, with proper aspect ratios!
  3. Color adder, single channel
  4. By: Chris M. Thomasson
  5. *_____________________________________________________________*/
  6.  
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include <complex.h>
  12. #include <tgmath.h>
  13. #include <stdbool.h>
  14.  
  15.  
  16. #define CT_WIDTH 1920
  17. #define CT_HEIGHT 1080
  18. #define CT_N 10000000
  19.  
  20.  
  21.  
  22. struct ct_rgb
  23. {
  24. unsigned char r;
  25. unsigned char g;
  26. unsigned char b;
  27. };
  28.  
  29.  
  30. struct ct_canvas
  31. {
  32. unsigned long width;
  33. unsigned long height;
  34. //unsigned char* buf;
  35. struct ct_rgb* buf;
  36. };
  37.  
  38. bool
  39. ct_canvas_create(
  40. struct ct_canvas* const self,
  41. unsigned long width,
  42. unsigned long height
  43. ){
  44. size_t size = width * height * sizeof(*self->buf);
  45.  
  46. self->buf = calloc(1, size);
  47.  
  48. if (self->buf)
  49. {
  50. self->width = width;
  51. self->height = height;
  52.  
  53. return true;
  54. }
  55.  
  56. return false;
  57. }
  58.  
  59. void
  60. ct_canvas_destroy(
  61. struct ct_canvas const* const self
  62. ){
  63. free(self->buf);
  64. }
  65.  
  66. bool
  67. ct_canvas_save_ppm(
  68. struct ct_canvas const* const self,
  69. char const* fname
  70. ){
  71. FILE* fout = fopen(fname, "wb");
  72.  
  73. if (fout)
  74. {
  75. // P6 by Bart over on:
  76. // https://groups.google.com/forum/#!original/comp.lang.c/4196m3Raggs/2moZ67o5EwAJ
  77.  
  78. char const ppm_head[] =
  79. "P6\n"
  80. "# Chris M. Thomasson Simple 2d Plane ver:0.0.0.0 (pre-alpha)";
  81.  
  82. fprintf(fout, "%s\n%lu %lu\n%u\n",
  83. ppm_head,
  84. self->width, self->height,
  85. 255U);
  86.  
  87. size_t size = self->width * self->height;
  88.  
  89. for (size_t i = 0; i < size; ++i)
  90. {
  91. //unsigned int c = self->buf[i];
  92. struct ct_rgb* c = self->buf + i;
  93.  
  94. fprintf(fout, "%c%c%c", c->r, c->g, c->b);
  95. //fprintf(fout, "%c%c%c", c, 0U, 0U);
  96. }
  97.  
  98. if (! fclose(fout))
  99. {
  100. return true;
  101. }
  102. }
  103.  
  104. return false;
  105. }
  106.  
  107.  
  108.  
  109.  
  110. struct ct_axes
  111. {
  112. double xmin;
  113. double xmax;
  114. double ymin;
  115. double ymax;
  116. };
  117.  
  118. struct ct_axes
  119. ct_axes_from_point(
  120. double complex z,
  121. double radius
  122. ){
  123. struct ct_axes axes = {
  124. creal(z) - radius, creal(z) + radius,
  125. cimag(z) - radius, cimag(z) + radius
  126. };
  127.  
  128. return axes;
  129. }
  130.  
  131.  
  132. struct ct_plane
  133. {
  134. struct ct_axes axes;
  135. double xstep;
  136. double ystep;
  137. };
  138.  
  139.  
  140. void
  141. ct_plane_init(
  142. struct ct_plane* const self,
  143. struct ct_axes const* axes,
  144. unsigned long width,
  145. unsigned long height
  146. ){
  147. self->axes = *axes;
  148.  
  149. double awidth = self->axes.xmax - self->axes.xmin;
  150. double aheight = self->axes.ymax - self->axes.ymin;
  151.  
  152. assert(width > 0 && height > 0 && awidth > 0.0);
  153.  
  154. double daspect = fabs((double)height / width);
  155. double waspect = fabs(aheight / awidth);
  156.  
  157. if (daspect > waspect)
  158. {
  159. double excess = aheight * (daspect / waspect - 1.0);
  160. self->axes.ymax += excess / 2.0;
  161. self->axes.ymin -= excess / 2.0;
  162. }
  163.  
  164. else if (daspect < waspect)
  165. {
  166. double excess = awidth * (waspect / daspect - 1.0);
  167. self->axes.xmax += excess / 2.0;
  168. self->axes.xmin -= excess / 2.0;
  169. }
  170.  
  171. self->xstep = (self->axes.xmax - self->axes.xmin) / width;
  172. self->ystep = (self->axes.ymax - self->axes.ymin) / height;
  173. }
  174.  
  175.  
  176.  
  177. struct ct_plot
  178. {
  179. struct ct_plane plane;
  180. struct ct_canvas* canvas;
  181. };
  182.  
  183.  
  184. void
  185. ct_plot_init(
  186. struct ct_plot* const self,
  187. struct ct_axes const* axes,
  188. struct ct_canvas* canvas
  189. ){
  190. ct_plane_init(&self->plane, axes, canvas->width - 1, canvas->height - 1);
  191. self->canvas = canvas;
  192. }
  193.  
  194.  
  195. bool
  196. ct_plot_add(
  197. struct ct_plot* const self,
  198. double complex z,
  199. struct ct_rgb const* color
  200. ){
  201. long x = (creal(z) - self->plane.axes.xmin) / self->plane.xstep;
  202. long y = (self->plane.axes.ymax - cimag(z)) / self->plane.ystep;
  203.  
  204. if (x > -1 && x < (long)self->canvas->width &&
  205. y > -1 && y < (long)self->canvas->height)
  206. {
  207. // Now, we can convert to index.
  208. size_t i = x + y * self->canvas->width;
  209.  
  210. assert(i < self->canvas->height * self->canvas->width);
  211.  
  212. struct ct_rgb exist = self->canvas->buf[i];
  213.  
  214. exist.r += 1;
  215.  
  216. self->canvas->buf[i] = exist;
  217. return true;
  218. }
  219.  
  220. return true;
  221. }
  222.  
  223.  
  224. bool
  225. ct_plot_pixel(
  226. struct ct_plot* const self,
  227. long x,
  228. long y,
  229. struct ct_rgb const* color
  230. ){
  231. if (x > -1 && x < (long)self->canvas->width &&
  232. y > -1 && y < (long)self->canvas->height)
  233. {
  234. // Now, we can convert to index.
  235. size_t i = x + y * self->canvas->width;
  236.  
  237. assert(i < self->canvas->height * self->canvas->width);
  238.  
  239. self->canvas->buf[i] = *color;
  240. return true;
  241. }
  242.  
  243. return false;
  244. }
  245.  
  246.  
  247. double complex
  248. ct_project_to_xy(
  249. struct ct_plot* const self,
  250. long x,
  251. long y
  252. ){
  253. double complex p =
  254. (self->plane.axes.xmin + x * self->plane.xstep) +
  255. (self->plane.axes.ymax - y * self->plane.ystep) * I;
  256.  
  257. return p;
  258. }
  259.  
  260.  
  261. bool
  262. ct_plot_point(
  263. struct ct_plot* const self,
  264. double complex z,
  265. struct ct_rgb const* color
  266. ){
  267. long x = (creal(z) - self->plane.axes.xmin) / self->plane.xstep;
  268. long y = (self->plane.axes.ymax - cimag(z)) / self->plane.ystep;
  269.  
  270. if (x > -1 && x < (long)self->canvas->width &&
  271. y > -1 && y < (long)self->canvas->height)
  272. {
  273. // Now, we can convert to index.
  274. size_t i = x + y * self->canvas->width;
  275.  
  276. assert(i < self->canvas->height * self->canvas->width);
  277.  
  278. self->canvas->buf[i] = *color;
  279. return true;
  280. }
  281.  
  282. return false;
  283. }
  284.  
  285.  
  286. // slow, so what for now... ;^)
  287. void ct_circle(
  288. struct ct_plot* const plot,
  289. double complex c,
  290. double radius,
  291. unsigned int n
  292. ){
  293. double abase = 6.2831853071 / n;
  294.  
  295. for (unsigned int i = 0; i < n; ++i)
  296. {
  297. double angle = abase * i;
  298.  
  299. double complex z =
  300. (creal(c) + cos(angle) * radius) +
  301. (cimag(c) + sin(angle) * radius) * I;
  302.  
  303. struct ct_rgb rgb = { 255, 255, 255 };
  304.  
  305. ct_plot_point(plot, z, &rgb);
  306. }
  307. }
  308.  
  309.  
  310. // Simple 3-ary vector impl, just what I need.
  311. struct ct_vec3
  312. {
  313. double x;
  314. double y;
  315. double z;
  316. };
  317.  
  318.  
  319. double ct_vev3_length(
  320. struct ct_vec3 const p
  321. ){
  322. double sum = p.x * p.x + p.y * p.y + p.z * p.z;
  323. return sqrt(sum);
  324. }
  325.  
  326.  
  327. struct ct_vec3
  328. ct_vec3_add(
  329. struct ct_vec3 const p,
  330. struct ct_vec3 const addend
  331. ){
  332. struct ct_vec3 sum = {
  333. p.x + addend.x,
  334. p.y + addend.y,
  335. p.z + addend.z
  336. };
  337.  
  338. return sum;
  339. }
  340.  
  341.  
  342. // The Mandelbulb, slice hardcoded
  343. // Animation comes next Owen.
  344. void
  345. ct_iterate_mbulb_pixel(
  346. struct ct_plot* const plot,
  347. struct ct_vec3 const z0,
  348. struct ct_vec3 const c0,
  349. long x,
  350. long y,
  351. unsigned int n
  352. ){
  353. struct ct_vec3 zs = z0;
  354. struct ct_vec3 cs = c0;
  355.  
  356. double power = 3.0;
  357.  
  358. for (unsigned long i = 0; i < n; ++i)
  359. {
  360. double r = ct_vev3_length(zs);
  361. double rpower = pow(r, power);
  362.  
  363. double angle0 = atan2(zs.z, sqrt(zs.x * zs.x + zs.y * zs.y));
  364. double angle1 = atan2(zs.y, zs.x);
  365.  
  366. struct ct_vec3 znew;
  367. znew.x = rpower * cos(power * angle1) * cos(power * angle0);
  368. znew.y = rpower * sin(power * angle1) * cos(power * angle0);
  369. znew.z = rpower * sin(power * angle0);
  370.  
  371. zs = ct_vec3_add(znew, cs);
  372.  
  373. if (r > 2.0)
  374. {
  375. return;
  376. }
  377. }
  378.  
  379. struct ct_rgb rgb = { 0, 255, 0 };
  380. ct_plot_pixel(plot, x, y, &rgb);
  381. }
  382.  
  383.  
  384. // Gain the field...
  385. void
  386. ct_iterate_mbulb_plane(
  387. struct ct_plot* const plot,
  388. unsigned int n
  389. ){
  390. for (long y = 0; y < plot->canvas->height; ++y)
  391. {
  392. for (long x = 0; x < plot->canvas->width; ++x)
  393. {
  394. double complex cz = ct_project_to_xy(plot, x, y);
  395.  
  396. // Well, our per slice coords...
  397. struct ct_vec3 z;
  398.  
  399. z.x = creal(cz);
  400. z.y = cimag(cz);
  401. z.z = 0.1;
  402.  
  403. // Iterate the slice
  404. ct_iterate_mbulb_pixel(plot, z, z, x, y, n);
  405. }
  406. }
  407. }
  408.  
  409.  
  410.  
  411.  
  412. void ct_test_plane(
  413. struct ct_plot* const plot
  414. ){
  415. ct_iterate_mbulb_plane(plot, 64);
  416.  
  417. ct_circle(plot, 0+0*I, 1.0, 2048);
  418. }
  419.  
  420.  
  421. int main(void)
  422. {
  423. struct ct_canvas canvas;
  424.  
  425. if (ct_canvas_create(&canvas, CT_WIDTH, CT_HEIGHT))
  426. {
  427. double complex plane_origin = 0+0*I;
  428. double plane_radius = 2.0;
  429.  
  430. struct ct_axes axes = ct_axes_from_point(plane_origin, plane_radius);
  431.  
  432. struct ct_plot plot;
  433. ct_plot_init(&plot, &axes, &canvas);
  434.  
  435.  
  436. ct_test_plane(&plot);
  437.  
  438.  
  439. // Our unit circle
  440. ct_circle(&plot, 0+0*I, 1.0, 2048);
  441. ct_circle(&plot, 2+0*I, 2.0, 2048);
  442. ct_circle(&plot, -2+0*I, 2.0, 2048);
  443. ct_circle(&plot, 0+2*I, 2.0, 2048);
  444. ct_circle(&plot, 0-2*I, 2.0, 2048);
  445.  
  446. ct_canvas_save_ppm(&canvas, "ct_plane.ppm");
  447.  
  448. ct_canvas_destroy(&canvas);
  449.  
  450. return EXIT_SUCCESS;
  451. }
  452.  
  453. return EXIT_FAILURE;
  454. }
Advertisement
Add Comment
Please, Sign In to add comment