fgraph_precision.pl 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 02 July 2014
  5. # Edit: 15 July 2014
  6. # https://github.com/trizen
  7. # Map a mathematical function on the xOy axis.
  8. use 5.010;
  9. use strict;
  10. use autodie;
  11. use warnings;
  12. use GD::Simple qw();
  13. use Getopt::Long qw(GetOptions);
  14. my $e = exp(1);
  15. my $pi = atan2(0, -'inf');
  16. my $size = 150;
  17. my $step = 1e-2;
  18. my $from = -5;
  19. my $to = abs($from);
  20. my $v = !1;
  21. my $f = sub { my ($x) = @_; $x**2 + 1 };
  22. my $output_file = 'function_graph.png';
  23. GetOptions(
  24. 'size|s=f' => \$size,
  25. 'step=f' => \$step,
  26. 'from=f' => \$from,
  27. 'to|t=f' => \$to,
  28. 'verbose|v!' => \$v,
  29. 'output|o=s' => \$output_file,
  30. 'function|f=s' => sub {
  31. my (undef, $value) = @_;
  32. $f = eval("sub {my(\$x) = \@_; $value}") // die "Invalid function '$value': $@";
  33. },
  34. )
  35. || die("Error in command line arguments\n");
  36. # Generic creation of a matrix
  37. sub create_matrix {
  38. my ($size, $val) = @_;
  39. int($size / 2), [map { [($val) x ($size)] } 0 .. $size - 1];
  40. }
  41. # Create a matrix
  42. my ($i, $matrix) = create_matrix($size, ' ');
  43. # Assign the point inside the matrix
  44. sub assign {
  45. my ($x, $y, $value) = @_;
  46. $x += $i;
  47. $y += $i;
  48. $matrix->[-$y][$x] = $value;
  49. }
  50. # Map the function
  51. for (my $x = $from ; $x <= $to ; $x += $step) {
  52. my $y = eval { $f->($x) };
  53. if ($@) {
  54. warn "f($x) is not defined!\n";
  55. next;
  56. }
  57. $y = sprintf('%.0f', $y);
  58. say "($x, $y)" if $v; # this line prints the coordinates
  59. assign($x, $y, 'o'); # this line maps the value of (x, f(x)) on the graph
  60. }
  61. # Init the GD::Simple module
  62. my $img = GD::Simple->new($i * 2, $i * 2);
  63. sub l {
  64. $img->line(shift);
  65. }
  66. sub c {
  67. $img->fgcolor(shift);
  68. }
  69. sub mv {
  70. $img->moveTo(@_);
  71. }
  72. mv(0, 0);
  73. # Create the image from the 2D-matrix
  74. while (my ($k, $row) = each @{$matrix}) {
  75. while (my ($l, $col) = each @{$row}) {
  76. if ($col eq ' ') {
  77. if ($k == $i) { # the 'x' line
  78. c('white');
  79. l(1);
  80. }
  81. elsif ($l == $i) { # the 'y' line
  82. c('white');
  83. l(1);
  84. }
  85. else { # space
  86. c('black');
  87. l(1);
  88. }
  89. }
  90. else { # everything else
  91. c('red');
  92. l(1);
  93. }
  94. }
  95. mv(0, $k + 1);
  96. }
  97. # Create the PNG file
  98. open my $fh, '>', $output_file or die "$output_file: $!";
  99. print {$fh} $img->png;
  100. close $fh;