2017-11-02 16 views
0

EasyPaintというプログラムでシフトキーを押したときに、まっすぐな垂直/水平線を実装する作業を行っています。コードにエラーはありませんが、残念ながらプログラム自体には全く影響しません。私が線を引いてシフトを押すと、絶対に何もしません。以下のコードは私のメソッドshiftPressEventと私の他のメソッドisModです。私はラインを垂直アラインメントまたは水平アラインメントにスナップする必要があるかどうかを計算するために度の計算を試みましたが、明らかに意図された仕事をしていないようです。別の目が多分コードを分析して、どこに問題があるのか​​を知ることができれば、私は大いに感謝しています。また、それ以上の情報が必要な場合は、以下にコメントしてください。私はLineInstrumentのクラス全体を簡単に投稿できますが、かなり長いです。シフトキー(C++とQt 5.8)を押したときの完全直線/垂直線

編集する前にLineInstrument.cppで追加されたメソッド

void LineInstrument::shiftPressEvent(QKeyEvent *event, ImageArea &imageArea){ 
if (imageArea.isPaint()) 
{ 
    imageArea.setImage(mImageCopy); 
    double Y = mStartPoint.y() - mEndPoint.y(); 
    double X = mStartPoint.x() - mEndPoint.x(); 

    radianAngle = atan2(Y, X); 
    degreeAngle = radianAngle * 180/atan(1) * 4; 

    if (isMod(event->key())) 
    { 
     if (abs(degreeAngle) >= 45 && abs(degreeAngle) <= 135) 
     { 
      mEndPoint.setX(mStartPoint.x()); 
     } 

     else if (abs(degreeAngle) < 45 && abs(degreeAngle) > 135) 
     { 
      mEndPoint.setY(mStartPoint.y()); 
     } 

     imageArea.update(); 
    } 
} 
} 

bool LineInstrument::isMod(int key){ 
if (key == Qt::Key_Shift) 
{ 
    return true; 
} 

return false; 
} 

編集した後LineInstrument.cppで追加されたメソッド

void LineInstrument::shiftPressEvent(QKeyEvent *event, ImageArea &imageArea) 
{ 
    if (imageArea.isPaint()) 
    { 
     imageArea.setImage(mImageCopy); 
     double Y = mStartPoint.y() - mEndPoint.y(); 
     double X = mStartPoint.x() - mEndPoint.x(); 

     if (isMod(event->key()) && fabs(X) > fabs(Y)) 
     { 
      mEndPoint.setY(mStartPoint.y()); 
      paint(imageArea, false); 
     } 

     else if (isMod(event->key()) && fabs(Y) >= fabs(X)) 
     { 
      mEndPoint.setX(mStartPoint.x()); 
      paint(imageArea, false); 
     } 

    } 
} 

    bool LineInstrument::isMod(int key) 

{ 
    if (key == Qt::Key_Shift) 
    { 
     return true; 
    } 

    return false; 
} 

LineInstrumentヘッダーファイルを編集する前に

#ifndef LINEINSTRUMENT_H 
#define LINEINSTRUMENT_H 

#include "abstractinstrument.h" 

#include <QtCore/QObject> 
#include <QKeyEvent> 

/** 
* @brief Line instrument class. 
* 
*/ 
class LineInstrument : public AbstractInstrument 
{ 
    Q_OBJECT 

public: 
    explicit LineInstrument(QObject *parent = 0); 

    void mousePressEvent(QMouseEvent *event, ImageArea &imageArea); 
    void mouseMoveEvent(QMouseEvent *event, ImageArea &imageArea); 
    void mouseReleaseEvent(QMouseEvent *event, ImageArea &imageArea); 
    void shiftPressEvent(QKeyEvent *event, ImageArea &imageArea); 
    bool isMod(int key); 
protected: 
    void paint(ImageArea &imageArea, bool isSecondaryColor = false, bool additionalFlag = false); 

private: 
    double radianAngle; 
    double degreeAngle; 
}; 

#endif // LINEINSTRUMENT_H 

LineInstrumentヘッダーファイルは、問題の編集

#ifndef LINEINSTRUMENT_H 
#define LINEINSTRUMENT_H 

#include "abstractinstrument.h" 

#include <QtCore/QObject> 
#include <QKeyEvent> 

/** 
* @brief Line instrument class. 
* 
*/ 
class LineInstrument : public AbstractInstrument 
{ 
    Q_OBJECT 

public: 
    explicit LineInstrument(QObject *parent = 0); 

    void mousePressEvent(QMouseEvent *event, ImageArea &imageArea); 
    void mouseMoveEvent(QMouseEvent *event, ImageArea &imageArea); 
    void mouseReleaseEvent(QMouseEvent *event, ImageArea &imageArea); 
    void shiftPressEvent(QKeyEvent *event, ImageArea &imageArea); 
    bool isMod(int key); 
protected: 
    void paint(ImageArea &imageArea, bool isSecondaryColor = false, bool additionalFlag = false); 
}; 

#endif // LINEINSTRUMENT_H 
+0

これらのメソッドが呼び出されていますか?あなたは何の要素を描いていますか? – eyllanesc

+0

imageAreaを継承するクラスは何ですか? – eyllanesc

+0

@eyllanesc imageAreaを継承するクラスはQWidgetだと私は信じています。また、LineInstrumentのすべてのメソッドで「View Call Hierarchy」を実行しましたが、実際にどこでも呼び出されることはありませんが、EasyPaintプログラム内で動作するため、私のメソッドはどこでも呼び出す必要はないと想定していました。唯一の方法はコンストラクタです。 – Chay

答えて

0

部分の後にあなたが適切度の角度を計算していないということです。この行は、あなたはそれがないと思う何をしませんと同じだ

degreeAngle = radianAngle * 180/atan(1) * 4; 

degreeAngle = 4 * radianAngle * 180/atan(1); 

あなたはこのような何かを行うことによって、PIのための適切という名前の定数を作成している実行する必要があります。

const double kPi = atan(1.0) * 4.0; 

そして、あなたは、おそらくこのようなラジアンを度に変換する関数を作成する必要があります。

double toDegrees(double radians) 
{ 
    return radians * 180.0/kPi; 
} 

xデルタとyデルタを単純に比較することで、水平スナップと垂直スナップの方がはるかに簡単かどうかを判断することもできます。 XYより大きい場合は水平線が必要です。そうでない場合は垂直線が必要です。さて、これはあなたの問題を解決するかどうかを

if (fabs(X) > fabs(Y)) 
{ 
    mEndPoint.setY(mStartPoint.y()); 
} 
else 
{ 
    mEndPoint.setX(mStartPoint.x()); 
} 

図面は、実際に発生した方法によって異なります。このような何かはトリックを行う必要があります。

+0

うーん...私はあなたのアドバイスを心に奪い、度/ラジアンで行うすべてを取り除き、単にxとyのデルタを比較しました。残念ながら、まだ影響はありません。 – Chay

+0

デバッガでコードをステップ実行して、期待通りに描画していない理由を確認しましたか? 'shiftPressEvent()'メソッドにブレークポイントを置いて、それがあなたが思った通りに実行しているかどうかを確認することをお勧めします。その関数の 'mEndPoint'はどうなりますか?次に、 'paint()'メソッドにブレークポイントを置き、 'mEndPoint'がどのように見えるかを見てみましょう。彼らは一致しますか?線が正しく描かれましたか? – user1118321