描画像を正方形⇒菱形すだれ様に変換したい

解決


hannya  URL  2011-12-20 16:16:29  No: 73047  IP: 192.*.*.*

お世話になります。
現状は直交坐要のX,Yで描画をしています。
void CChildView::OnPaint()
{
  // TODO: Add your message handler code here

  CPaintDC dc(this); // device context for painting

  CMemDC memDC;
  memDC.CreateDIBitmap( m_imageSiH, m_imageSiV );  // creat an image area in the window
  memDC.FillSolidRect(0, 0, m_imageSiH, m_imageSiV, m_grdColor); //ground color

以下描画をします。
この描画のコードをそのままにして、正方形に配列されている点や線の描画像を、菱形(横の長さは同じで、横位置と縦位置・縦の長さは変換される=すだれ様の変形になる)に変換したい。出来るでしょうか?
例えば
dc.BitBlt(0, 0, m_imageSiH, m_imageSiV, &memDC, 0, 0, SRCCOPY);
の前になにか  コードをいれたら  画面全体を変換するというようnことはできないものでしょうか?

編集 削除
hannya  URL  2011-12-21 06:49:52  No: 73048  IP: 192.*.*.*

慌てて  環境を忘れました。WindowsXP  VC++6.0MFCで作成しています
PhotoShopで菱形に変形する操作があります。今これを用いているのですが
描画ソフト内でできないかと。
それと正方格子の交点が菱形に、そして  正五角形の配置になることを期待しています。横の長さは不変で  横に移動し、縦は回転するにで  長さが変わる。
では  ぜひ  助言をおねがいします

編集 削除
hannya  2011-12-21 07:13:23  No: 73049  IP: 192.*.*.*

訂正  正5角形と書いたのはミスです。正6角形です
しかし  擬似立体表現を狙ったわけではないのでクォータービューをめざしているわけではありません。単純に平面上での変形です
よろしく  おねがいします

編集 削除
hannya  2011-12-21 16:23:16  No: 73050  IP: 192.*.*.*

ご検討ありがとうございます
数値的には
まず  横座標X=x+y/2(X軸上スライドさせる)
つぎに縦座標Y=y*(√3)/2(菱形斜辺長さが1になるべく、Y軸上で縮小させる)
これを描画された像全体に適用して  変形させることを期待します
よろしく  おねがいします

編集 削除
gak  2011-12-21 18:43:54  No: 73051  IP: 192.*.*.*

正直、hannya さんが望んでいる最終形態が俺には全く見えていない。なので「菱形」という単語のみに反応しての回答。
# 多分、翻訳時に結構な齟齬(difference)が発生してる。そのため hannya さんの状況、望む事等が正確に伝わっていないかも


// まず  横座標X=x+y/2(X軸上スライドさせる)
// つぎに縦座標Y=y*(√3)/2(菱形斜辺長さが1になるべく、Y軸上で縮小させる)
cosnt POINT points[3] = {
    { 0, 0 },
    { 0 + size.cx, 0 },
    { 0 + m_imageSiH / 2, LONG(m_imageSiV * 1.73205081 / 2 + 0.5) }
};
// dc.BitBlt(0, 0, m_imageSiH, m_imageSiV, &memDC, 0, 0, SRCCOPY);
dc.PlgBlt(points, &memDC, 0, 0, m_imageSiH, m_imageSiV, CBitmap(), 0, 0);

編集 削除
hannya  2011-12-22 09:23:04  No: 73052  IP: 192.*.*.*

ありがとうございます。
以下のようにコードを書き換えると
POINT points[3] = { 0,0, 0 +size.cx,0, 0 +m_imageSiH/2,LONG(m_imageSiV *1.73205081/2 +0.5) };

size.cxが定義されていないと出ます。これはなにを意味しているでしょうか?
どうすれば解決しますか?

編集 削除
gak  2011-12-22 13:10:42  No: 73053  IP: 192.*.*.*

cosnt POINT points[3] = {
    { 0, 0 },
    { 0 + m_imageSiH, 0 },
    { 0 + m_imageSiV / 2, LONG(m_imageSiV * 1.73205081 / 2 + 0.5) }
};

間違ってた…こうだね。


マジックナンバー無しで説明するなら↓な事を意図してる

// dc.BitBlt(x, y, width, height, &memDC, 0, 0, SRCCOPY);
cosnt POINT points[3] = {
    { x, y },
    { x + width, y },
    { x + height / 2, LONG((height * sqrt(3.0) / 2) + 0.5) }
};
dc.PlgBlt(points, &memDC, 0, 0, width, height, CBitmap(), 0, 0);

編集 削除
hannya  2011-12-22 16:59:59  No: 73054  IP: 192.*.*.*

ありがとうございました  ばっちりです。
こんな便利な関数?クラス?があるのですね。やはり使いこなすには相当勉強を要する。適切な助言を助かりました。

元に戻すのはあるでしょうか?一度描画したものは戻れないかな?
それとも
// dc.BitBlt(0, 0, m_imageSiH, m_imageSiV, &memDC, 0, 0, SRCCOPY);
と切り替えれば良いかもしれません。
いろいろやってみます。一応  解決印しにしますが
上のことで助言があればおねがいします

編集 削除
hannya  2011-12-22 17:00:47  No: 73055  IP: 192.*.*.*

ありがとうございました

編集 削除
gak  2011-12-22 18:22:25  No: 73056  IP: 192.*.*.*

> 元に戻すのはあるでしょうか?一度描画したものは戻れないかな?
関数一つで元に戻せるようなAPIは用意されていない。なので、
> それとも
> // dc.BitBlt(0, 0, m_imageSiH, m_imageSiV, &memDC, 0, 0, SRCCOPY);
> と切り替えれば良いかもしれません。
等、hannya さんにとって適当な方法を用いて機能を自力で実装する必要がある。


後、先の回答内容だけど下記に修正…
> { x + height / 2, LONG((height * sqrt(3.0) / 2) + 0.5) }
  { x + height / 2, y + LONG((height * sqrt(3.0) / 2) + 0.5) }

編集 削除
maru  2011-12-22 18:45:11  No: 73057  IP: 192.*.*.*

> 元に戻すのはあるでしょうか?一度描画したものは戻れないかな?
正方形を斜めに押しつぶしたんですよね。
面積が87%((√3)/2)になったのだから情報は失われているはず。
その情報をどうやって補完してあげるのかなぁ。

編集 削除
hannya  2011-12-23 08:18:28  No: 73058  IP: 192.*.*.*

ありがとうございます
切替式にします
{ x + height / 2, y + LONG((height * sqrt(3.0) / 2) + 0.5) }
の最後の+0.5は四捨五入するためですね  

これで正方格子での線描画がTopologicalですが正三角形格子(あるいは正六角形)上での描画になりました  傾きを逆
{ 0, 0,  +m_imageSiH, 0, -m_imageSiV/2,
にしました。後で傾斜部分を切り足らないで済ますため。
ありがとうございました

編集 削除
hannya  2011-12-27 07:58:37  No: 73059  IP: 192.*.*.*

小生が期待し、コードを教えて頂いたのはアフィン変換と言うものらしいです。
縮小でも  数学的には線形変換です  可逆であるから、情報が失われることはないのですが  解像度以下の像が復元できません。直線は直線に移行する。線分長の比が同じ。
それもあるのですが、表示の収まりが良いように、縦軸はそのままのスケールで
横軸だけ変形させて、元正方格子InLine dot arrayを正三角形(正五角形・菱形)格子 InBetween dot arrayに変形させました。
//m_imageSiV/4 全体中心を右シフト// 下左傾き60度
POINT plgpnts[3] = { m_imageSiV/4, 0,  m_imageSiV/4 +m_imageSiH,0,  m_imageSiV/4 -m_imageSiV/2, m_imageSiV };  
                                    
ありがとうございました

編集 削除
hannya  2011-12-27 08:54:18  No: 73060  IP: 192.*.*.*

画面上で実測すると横辺に対して斜辺がやや長くなる  ??
幾何学をもう一度おさらい  さらに吟味をします

編集 削除
hannya  2011-12-27 08:54:18  No: 73061  IP: 192.*.*.*

画面上で実測すると横辺に対して斜辺がやや長くなる  ??
幾何学をもう一度おさらい  さらに吟味をします

編集 削除
hannya  2011-12-29 07:55:06  No: 73062  IP: 192.*.*.*

ありがとうございました
やっと算数幾何をやりなおして  縦軸はそのままで  正方格子を正三角・正五画格子に変形できました  以下3点の座標です
POINT plgpnts[3] = { m_imageSiV/7, 0,  m_imageSiV/7 +LONG(m_imageSiH*2/sqrt(3.0) +0.5), 0,  m_imageSiV/7 -LONG(m_imageSiV/sqrt(3.0) +0.5), m_imageSiV }; //下左傾き 
//m_imageSiV/7 全体を右シフト

さあ  次の改善  保存です

編集 削除
hannya  2011-12-29 07:59:53  No: 73063  IP: 192.*.*.*

また  あわてもした  正五角形ではなく  正六角形です

寒くて  マウスをもつ指も  Keyを打つ指先も凍ります  手袋しているのに  !

編集 削除