gpt4 book ai didi

c++ - 使用没有图形的c++绘制线

转载 作者:太空狗 更新时间:2023-10-29 20:09:20 25 4
gpt4 key购买 nike

我希望在不使用图形库的情况下使用 c++ lang 编写画线的程序我尝试了很多但我没有达到我想要的结果线方程是:

y=mx+b

我想画这条线(举例)

y=3x+2

这是我的代码

#include <iostream>
#include <math.h>

using namespace std;

int pth (int x) {
return 2*x-3;
}

int main() {
int i,j,y;
for (int x=-10;x <= 10;x++) {
for ( i=-10;i <= x;i++) {
if (i==x) {
y=pth(x);
cout<<"x=";
cout<<x;
cout<<"y=";
cout<<y;

for(j=-10;j<=y;j++) {
if(j==y)
cout << "*";
else
cout << " ";
}
}
}
cout << "\n";
}
cin.get();
return 0;
}

输出是这样的

x=0y=3   *
x=1y=5 *
x=2y=7 *
x=3y=9 *
x=4y=11 *
x=5y=13 *
x=6y=15 *
x=7y=17 *
x=8y=19 *
x=9y=21 *
x=10y=23 *

但对于给定的方程 (y=2x-3),结果必须是

                                      *
*
*
*
*
*
*

我认为代码是正确的,但问题是如何确定线的方向以便正确绘制

最佳答案

因为我喜欢挑战,所以我制作了一个很小的 ​​Canvas 类,可以像这样使用:

int main() {
using Canvas = BasicCanvas<160, 80>;
Canvas canvas;
canvas.origin = {canvas.cols()/3, canvas.rows()/3};

canvas.axes();

canvas.plot([](double x) { return x; });
canvas.plot([](double ) { return -8; });
canvas.plot([](double x) { return 3*log(x); });
canvas.plot([](double x) { return 4*sin(x/2); });
canvas.plot([](double x) { return 24*cos(x/12); });

std::cout << canvas;
}

打印 enter image description here

或者注释掉原点赋值:enter image description here

实现

该实现基本上遍历 x 轴上的位置,并根据函数在该点的角度(一阶导数)绘制近似线图字符:

template <size_t Columns = 100, size_t Rows = 50>
struct BasicCanvas {
using Line = std::array<char, Columns>;
using Screen = std::array<Line, Rows>;
struct Coord { size_t x, y; };

static constexpr size_t rows() { return Rows; }
static constexpr size_t cols() { return Columns; }

Screen screen;
Coord origin;

BasicCanvas(Coord origin = {Columns/2, Rows/2}) : origin(origin) {
Line empty;
std::fill(empty.begin(), empty.end(), '.');
std::fill(screen.begin(), screen.end(), empty);
}

friend std::ostream& operator<<(std::ostream& os, BasicCanvas const& c) {
for (auto& line : c.screen) {
os.write(line.data(), line.size()) << "\n";
}
return os;
}

Line& operator[](size_t y) { return screen.at(screen.size()-(y+1)); }
Line const& operator[](size_t y) const { return screen.at(screen.size()-(y+1)); }
char& operator[](Coord coord) { return operator[](coord.y).at(coord.x); }
char const& operator[](Coord coord) const { return operator[](coord.y).at(coord.x); }

void axes() {
for (auto& line : screen)
line.at(origin.x) = '|';

auto& y_axis = operator[](origin.y);

for (auto& cell : y_axis)
cell = '-';

y_axis.at(origin.x) = '+';
}

template <typename F>
void plot(F f, double scaleX = 1.0, double scaleY = 1.0) {
for (size_t x_tick = 0; x_tick < Columns; ++x_tick) {
auto x = (x_tick * scaleX) - origin.x;
auto y = f(x);
auto y_ = derivative(f, x, scaleX/2);

size_t y_tick = (y / scaleY) + origin.y;
if (y_tick < Rows)
operator[]({x_tick, y_tick}) = glyph(y_);
}
}

private:
template <typename F>
auto derivative(F const& f, double x, double dx = 0.01) {
return (f(x+dx)-f(x-dx))/(2*dx);
}

char glyph(double tangent) {
auto angle = atan(tangent);

while (angle < 0)
angle += 2*M_PI;

int angle_index = 2.0 * angle / atan(1);

return R"(--/||\--)"[angle_index % 8];
}

};

完整 list

Live On Coliru

(简化函数选择):

#include <iostream>
#include <array>
#include <cmath>

template <size_t Columns = 100, size_t Rows = 50>
struct BasicCanvas {
using Line = std::array<char, Columns>;
using Screen = std::array<Line, Rows>;
struct Coord { size_t x, y; };

static constexpr size_t rows() { return Rows; }
static constexpr size_t cols() { return Columns; }

Screen screen;
Coord origin;

BasicCanvas(Coord origin = {Columns/2, Rows/2}) : origin(origin) {
Line empty;
std::fill(empty.begin(), empty.end(), ' ');
std::fill(screen.begin(), screen.end(), empty);
}

friend std::ostream& operator<<(std::ostream& os, BasicCanvas const& c) {
for (auto& line : c.screen) {
os.write(line.data(), line.size()) << "\n";
}
return os;
}

Line& operator[](size_t y) { return screen.at(screen.size()-(y+1)); }
Line const& operator[](size_t y) const { return screen.at(screen.size()-(y+1)); }
char& operator[](Coord coord) { return operator[](coord.y).at(coord.x); }
char const& operator[](Coord coord) const { return operator[](coord.y).at(coord.x); }

void axes() {
for (auto& line : screen)
line.at(origin.x) = '|';

auto& y_axis = operator[](origin.y);

for (auto& cell : y_axis)
cell = '-';

y_axis.at(origin.x) = '+';
}

template <typename F>
void plot(F f, double scaleX = 1.0, double scaleY = 1.0) {
for (size_t x_tick = 0; x_tick < Columns; ++x_tick) {
auto x = (x_tick * scaleX) - origin.x;
auto y = f(x);
auto y_ = derivative(f, x, scaleX/2);

size_t y_tick = (y / scaleY) + origin.y;
if (y_tick < Rows)
operator[]({x_tick, y_tick}) = glyph(y_);
}
}

private:
template <typename F>
auto derivative(F const& f, double x, double dx = 0.01) {
return (f(x+dx)-f(x-dx))/(2*dx);
}

char glyph(double tangent) {
auto angle = atan(tangent);

while (angle < 0)
angle += 2*M_PI;

int angle_index = 2.0 * angle / atan(1);

return R"(--/||\--)"[angle_index % 8];
}

};

int main() {
using Canvas = BasicCanvas<60, 30>;
Canvas canvas;
//canvas.origin = {canvas.cols()/3, canvas.rows()/3};

canvas.axes();

canvas.plot([](double x) { return x; });
//canvas.plot([](double ) { return -8; });
canvas.plot([](double x) { return 3*log(x); });
canvas.plot([](double x) { return 4*sin(x/2); });
//canvas.plot([](double x) { return 24*cos(x/12); });

std::cout << canvas;
}

打印

                              |             /               
| /
| /
| /
| / -
| / --------
| / ------
| / ----
| / ---
| /--
| --
--- --\ | /-- --\ /--
/ \ / | / \ /
/ \ |/ \ /
-----/-----\------------------/|----\------/----------------
/ \ /| \ /
/ \ //| \ /
\ / \ / | / \ /
--/ \-- --/ | \-- ---
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |
/ |

关于c++ - 使用没有图形的c++绘制线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47753700/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com