は手動で図形を描画するためにループすることは非常に困難となり。
だから、ある時点で、(K.ショアーズが言及したncursesのような)テキスト描画ライブラリを使いたいと思うでしょう。 main()
出力に
#include <iostream>
namespace auto_list_exploit {
static auto li = {1,2};
using initializer_list = decltype(li);
}
template <typename CT=char>
class TextSurface {
using initializer_list = auto_list_exploit::initializer_list;
public:
struct point {
int x,y;
point(int x=0, int y=0) : x(x), y(y) {}
point(initializer_list list) : x((list.begin())[0]), y((list.begin())[1]) {}
};
private:
int m_width, m_height, m_data_count;
CT* m_data;
int OffsetOf(int x, int y) const { return y * m_width + x; }
bool IsInside(int x, int y) { return x >= 0 && y>= 0 && x < m_width && y < m_height; }
CT& at(int x, int y) { return m_data[OffsetOf(x,y)]; }
CT at(int x, int y) const { return m_data[OffsetOf(x,y)]; }
int Abs(int x) { return x < 0 ? -x : x; }
void Poly(const point& pfirst, CT value, const point& plast) {
Line(plast, pfirst, value);
}
template <typename ...Ts>
void Poly(const point& pfirst, CT value, const point& p0, const point& p1, Ts...args) {
Line(p0, p1, value);
Poly(pfirst, value, p1, args...);
}
public:
TextSurface(int width=0, int height=0) :
m_width(height ? width : 0),
m_height(width ? height : 0),
m_data_count(width * height)
{
m_data = m_data_count ? new CT[m_data_count] : nullptr;
Clear();
}
// Cannot copy
TextSurface(const TextSurface&) =delete;
TextSurface& operator = (const TextSurface&) =delete;
// Can return from functions
TextSurface& operator = (TextSurface&& src) {
delete [] m_data;
m_width = src.m_width; m_height = src.m_height; m_data_count = src.m_data_count;
m_data = src.m_data;
src.m_data = nullptr;
return *this;
}
TextSurface(TextSurface&& src) : m_data(nullptr) { operator = ((TextSurface&&)src); }
~TextSurface() { delete [] m_data; }
int Width() const { return m_width; }
int Height() const { return m_height; }
void Clear(CT value=' ') {
CT* p = m_data;
CT* pe = p + m_data_count;
while(p != pe) *(p++) = value;
}
void Line(int x0, int y0, int x1, int y1, CT value) {
const int dx = x1-x0;
const int dy = y1-y0;
if(!dx && !dy) {
if(IsInside(x0, y0)) { at(x0, y0) = value; }
return;
}
const bool ymajor = Abs(dy) > Abs(dx);
int x=x0, y=y0;
int &mj = ymajor ? y : x;
int &mn = ymajor ? x : y;
const int mje = ymajor ? y1 : x1;
const int mjst = mj < mje ? 1 : -1;
double mnd = mn;
double mnst = ymajor ? double(dx)/Abs(dy) : double(dy)/Abs(dx);
do {
mn = int(mnd + 0.5);
if(IsInside(x,y)) { at(x,y) = value; }
mj += mjst;
mnd += mnst;
} while(mj != mje+mjst);
}
void Line(const point& p0, const point& p1, CT value) { Line(p0.x, p0.y, p1.x, p1.y, value); }
template <typename ...Ts>
void Poly(CT value, const point& p0, const point& p1, Ts...args) {
Line(p0, p1, value);
Poly(p0, value, p1, args...);
}
// init-list overloads for triangle and quad (initializer_list can't be packed)
void Poly(CT value, initializer_list l0, initializer_list l1, initializer_list l2) { Poly(value, point(l0), point(l1), point(l2)); }
void Poly(CT value, initializer_list l0, initializer_list l1, initializer_list l2, initializer_list l3) { Poly(value, point(l0), point(l1), point(l2), point(l3)); }
void Rect(int x, int y, int width, int height, CT value) {
Poly(value, point(x,y), point(x+width-1, y), point(x+width-1, y+height-1), point(x, y+height-1));
}
// Label places text. xloc selects the meaning of the x coordinate.
// Its value is between -1 and 1: -1 for x at the left of the text,
// 0 for x in the middle, and 1 for x at the end of the text.
void Label(const CT* text, int x, int y, double xloc=-1) {
int len = 0;
while(text[len]) { ++len; }
x -= int((xloc + 1)/2 * (len - 1));
for(int i=0; i<len; ++i) {
if(IsInside(x,y)) { at(x,y) = text[i]; }
++x;
} }
void Present() const {
const CT* p = m_data;
for(int j=0; j<m_height; ++j) {
std::cout.write(p, m_width);
std::cout << '\n';
p += m_width;
} }
};
typedef TextSurface<char> CharSurface;
int main() {
CharSurface surf(60,20);
surf.Poly('*', {20,2}, {34,16}, {20,16});
surf.Label("14 ft", 18, 10, 1);
surf.Label("9 ft", 26, 17, 0);
surf.Present();
}
http://ideone.com/i03DV8
例:
しかし、あなた自身の簡単な描画APIを転がすことは、脳の手術ではありません
*
**
* *
* *
* *
* *
* *
* *
14 ft * *
* *
* *
* *
* *
* *
***************
9 ft
は、私はこのような測定を入れたいですhttp://mdk12.msde.maryland.gov/assessments/high_school/look_like/geometry/images/q_5.gif –
ncursesを参照してください。 –
@ K.Shoresありがとう! –