アプリ版:「スタンプのみでお礼する」機能のリリースについて

 私は今、C++を勉強していますが、読んでいる本に付いている練習問題がありました、私が自分でやりましたが、うまくいかないです、助けてほしいです。
 以下は問題です。
 一つの円の中に4点を交わるように1つの長方形を描き、次にこの長方形に内接するように1つの円を描いていくことを繰り返す操作を考える。
 この操作をモデル化にするとき、どうすればいいでしょうか?
 よろしくお願いします。

A 回答 (3件)

プログラミングというより数学の問題みたいですね。



「以下は問題です。」の下の文は、練習問題の通り
なんでしょうか?何を求められているのか、
よくわかりません。

具体的には、以下の点が曖昧です。

1)「一つの円の中に4点を交わるように」とは、
円に内接するように、ということでしょうか?

そうだとすると、

2)「一つの円の中に4点を交わるように1つの
長方形を描き」というのは、円に内接する長方形を
描くことになります。ある円に内接する長方形という
のは無数に描けますが、どんな長方形をどんな向きで
描くのかはユーザが与えるんでしょうか?それとも
ランダム?

3)最初に円を与え、それに内接する長方形をユーザが与える
かランダムに決めるかして描けたとしましょう。すると、
さらにその長方形に内接する円も(この長方形が正方形で
ない限り)無数に描けますが、これはどうしましょう?
最初の円と同心円にしますか?

4)さらに、次に描いた円に内接する長方形も2)と同じ
理屈で無数に描けますが、一々ユーザが与えるんでしょうか?
それともランダムでしょうか?

…以下繰返し。
    • good
    • 0

モデル化に絞ってアドバイスです。

円クラスが子供の矩形クラスを所有し矩形クラスが子供の円クラスを所有、さらにその円クラスが矩形クラスを所有する構造をモデル化すればよいのですよね。
C++は処理を細分化・部品化することが得意ですし、とても重要です。今回の例では、親の情報から自分自身を作って、そして自分自身をさらに子供に渡す。子供がどのようなロジックで自分自身を作るのかは親は感知しません。(処理の部品化)
もっと高度の概念では、virtualを使った仮想関数で継承をサポートしたりもできます。(進化(?)した別のロジックで、自身を作るクラスを定義するなど・・)


下記は、円が真円・矩形が正方形を前提とした単純なモデル化の例です。
解説:
各クラスのコンストラクタが親のクラスのポインタを引き継ぎます。その情報を基に自身の情報を決定していきます。これで、ルートクラスをたったひとつ作ってやるだけであとはクラスが勝手に子供を作っていきます(^^)。


class CYen;
class CSquare;
static long nNestCount = 0L; // 繰り返し回数
#define NSTCNT 10 // 繰り返し制限値


class CYen//円クラス
{
private:
doublem_d;// 直径
CSquare* m_pChild;// 子 正方形クラス
public:
double D() const {return m_d;}
protected:
virtual void MakeParam(const CSquare*);
public:
CYen(const double d);// 開始のコンストラクタ
CYen(const CSquare*);// コンストラクタ
virtual ~CYen();// デストラクタ
};

class CSquare// 正方形クラス
{
private:
doublem_w;// 辺
CYen* m_pChild;// 子 円クラス
public:
double W() const {return m_w;}
protected:
virtual void MakeParam(const CYen*);
public:
CSquare(const CYen*);// コンストラクタ
virtual ~CSquare();// デストラクタ
};

CYen::CYen(const double d) : m_pChild(NULL), m_d(d)
{
ASSERT(m_d > 0.0);

nNestCount++;
if(nNestCount >= NSTCNT)return;
m_pChild = new CSquare(this);
}

CYen::CYen(const CSquare* pParent) : m_pChild(NULL)
{
nNestCount++;
if(nNestCount >= NSTCNT)return;
MakeParam(pParent);// 自分の形状を親矩形クラスの情報から作成する
m_pChild = new CSquare(this);
}

CYen::~CYen()
{
if(m_pChild)delete (CSquare*)m_pChild;
}

void CYen::MakeParam(const CSquare* pParent)
{
m_d = pParent->W();// 正方形と仮定すると、一辺長 = 直径
ASSERT(m_d > 0.0);
}

CSquare::CSquare(const CYen* pParent) : m_pChild(NULL)
{
nNestCount++;
if(nNestCount >= NSTCNT)return;
MakeParam(pParent);// 自分の形状を親円クラスの情報から作成する
m_pChild = new CYen(this);
}

CSquare::~CSquare()
{
if(m_pChild)delete (CYen*) m_pChild;
}

void CSquare::MakeParam(const CYen* pParent)
{
// 前提条件:内接図形は正方形
m_w = pParent->D() * sin(atan(1.0));
}

int main(void)
{
CYen(100.0); // ルートクラス 直径100の円 を作る
}

すいません長くなりました。
参考になれば幸いです。ではがんばってください。
    • good
    • 0

やや揚げ足取りの回答と取られかねないですが、No.2の方の回答はオブジェクトっぽく


ないです。「円」と「長方形」がクラスになっている、というのは納得できるんです
が、極かぎられた情報(内接する図形)が属性になっている、というのはいただけない。

class 円 {
public:
  円(中心の座標, 半径);
  ~円();
  長方形 get内接する長方形() const;
};

class 長方形 {
public:
  長方形(ある角の座標, その対角の座標);
  ~長方形();
  円 get内接する円(パラメータがあるかも) const;
};

ってな感じ。

あるオブジェクトの属性は、そのオブジェクトの性質を表すものです。
「ある長方形に内接する円」というのは、どう考えても属性では無いです。


更に、図形が長方形と円しか無い世界を考えるのであれば、

class 図形 {
protected:
  図形();
  virtual 図形();
  virtual 図形* get内接する図形() const;
};

class 円 : public 図形 {
public:
  円(中心の座標, 半径);
  ~円();
  図形* get内接する図形() const;
};

class 長方形 : public 図形 {
public:
  長方形(ある角の座標, その対角の座標);
  ~長方形();
  図形* get内接する図形() const;
};

図形* shape = 最初の図形;
while(終了条件) {
  shape = shape->get内接する図形();
  図形の描画;
}

ってな感じにできるかと。

# ちなみに、円に内接する *長方形* は無限にあるので、それを特定する
# 条件を何か考えなければ行けないですね
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!