void ParticleNeighborSearcher::searchSingleCell(const unsigned int& id, const GridCell& cell, NeighborTable& table)
{
	for(unsigned int i = 0; i < cell.mParticleIDs.size(); ++i)
	{
		unsigned int neighborId = cell.mParticleIDs[i];
		if(id == neighborId)
			continue;
		vec3 radial((*mParticles)[neighborId].mPosition - (*mParticles)[id].mPosition);
		float distSqr = glm::dot(radial, radial);
		if(distSqr < mSmoothRadius * mSmoothRadius)
			table[id].push_back(NeighborElem(neighborId, distSqr));
	}
}
示例#2
0
int test_create()
{
	int Error(0);

	gli::texture2D TextureA = radial(
		gli::texture2D::dimensions_type(128), gli::texture2D::texcoord_type(0.5), 16.f, gli::texture2D::texcoord_type(0.7));

	gli::texture2D TextureB = linear(
		gli::texture2D::dimensions_type(128), gli::texture2D::texcoord_type(0.5), gli::texture2D::texcoord_type(0.7));

	Error += TextureA != TextureB ? 0 : 1;

	return Error;
}
void RenderArea::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setPen(Qt::NoPen);
    painter.setRenderHint(QPainter::Antialiasing);


    if(currentBrush->style() == Qt::LinearGradientPattern) {
        currentBrush = new QBrush(QLinearGradient(0, 0, width(), 60));
    } else if(currentBrush->style() == Qt::RadialGradientPattern) {
        QRadialGradient radial(width() / 2, 30, width() / 2, width() / 2, 30);
        radial.setColorAt(0, Qt::white);
        radial.setColorAt(1, Qt::black);
        currentBrush = new QBrush(radial);
    } else if(currentBrush->style() == Qt::ConicalGradientPattern) {
        currentBrush = new QBrush(QConicalGradient(width() / 2, 30, 90));
    }
    painter.setBrush(*currentBrush);

    QPainterPath path;
    path.addRect(0, 0, parentWidget()->width(), 60);
    painter.drawPath(path);
}
示例#4
0
std::shared_ptr<RadialMenu> TreasuryManager::bankBuildTerminalRadialMenu(CreatureObject* creatureObject)
{
    std::shared_ptr<RadialMenu> radial(new RadialMenu());

    auto equip_service = gWorldManager->getKernel()->GetServiceManager()->GetService<swganh::equipment::EquipmentService>("EquipmentService");
	auto bank = dynamic_cast<Bank*>(equip_service->GetEquippedObject(creatureObject, "bank"));

    radial->addItem(1,0,radId_itemUse,radAction_ObjCallback);
    radial->addItem(2,1,radId_bankTransfer,radAction_ObjCallback,"@sui:bank_credits");

    // case its our bank
    if(static_cast<uint32>(bank->getPlanet()) == gWorldManager->getZoneId())
    {
        radial->addItem(3,1,radId_bankItems,radAction_ObjCallback,"@sui:bank_items");
        radial->addItem(4,1,radId_bankQuit,radAction_ObjCallback,"@sui:bank_quit");
        radial->addItem(5,1,radId_bankWithdrawAll,radAction_ObjCallback,"@sui:bank_withdrawall");
        radial->addItem(6,1,radId_bankDepositAll,radAction_ObjCallback,"@sui:bank_depositall");
    }

    // case we have no binded bank
    // Do not allow to join bank in tutorial, player will never be able to quit that bank when he/she has left tutorial.
    else if ((bank->getPlanet() < 0) && (!gWorldConfig->isTutorial()))
    {
        radial->addItem(3,1,radId_bankJoin,radAction_ObjCallback,"@sui:bank_join");
        radial->addItem(4,1,radId_bankWithdrawAll,radAction_ObjCallback,"@sui:bank_withdrawall");
        radial->addItem(5,1,radId_bankDepositAll,radAction_ObjCallback,"@sui:bank_depositall");
    }

    // case its not our bank
    else
    {
        radial->addItem(3,1,radId_bankWithdrawAll,radAction_ObjCallback,"@sui:bank_withdrawall");
        radial->addItem(4,1,radId_bankDepositAll,radAction_ObjCallback,"@sui:bank_depositall");
    }

    return radial;
}
示例#5
0
int main(int argc, char *argv[])
{
    // Info: reads only the _first_ 3D model in the NVM file!

    TCLAP::CmdLine cmd("LINE3D++");

    TCLAP::ValueArg<std::string> inputArg("i", "input_folder", "folder containing the images (if not specified, path in .nvm file is expected to be correct)", false, "", "string");
    cmd.add(inputArg);

    TCLAP::ValueArg<std::string> nvmArg("m", "nvm_file", "full path to the VisualSfM result file (.nvm)", true, ".", "string");
    cmd.add(nvmArg);

    TCLAP::ValueArg<std::string> outputArg("o", "output_folder", "folder where result and temporary files are stored (if not specified --> input_folder+'/Line3D++/')", false, "", "string");
    cmd.add(outputArg);

    TCLAP::ValueArg<int> scaleArg("w", "max_image_width", "scale image down to fixed max width for line segment detection", false, L3D_DEF_MAX_IMG_WIDTH, "int");
    cmd.add(scaleArg);

    TCLAP::ValueArg<int> neighborArg("n", "num_matching_neighbors", "number of neighbors for matching", false, L3D_DEF_MATCHING_NEIGHBORS, "int");
    cmd.add(neighborArg);

    TCLAP::ValueArg<float> sigma_A_Arg("a", "sigma_a", "angle regularizer", false, L3D_DEF_SCORING_ANG_REGULARIZER, "float");
    cmd.add(sigma_A_Arg);

    TCLAP::ValueArg<float> sigma_P_Arg("p", "sigma_p", "position regularizer (if negative: fixed sigma_p in world-coordinates)", false, L3D_DEF_SCORING_POS_REGULARIZER, "float");
    cmd.add(sigma_P_Arg);

    TCLAP::ValueArg<float> epipolarArg("e", "min_epipolar_overlap", "minimum epipolar overlap for matching", false, L3D_DEF_EPIPOLAR_OVERLAP, "float");
    cmd.add(epipolarArg);

    TCLAP::ValueArg<int> knnArg("k", "knn_matches", "number of matches to be kept (<= 0 --> use all that fulfill overlap)", false, L3D_DEF_KNN, "int");
    cmd.add(knnArg);

    TCLAP::ValueArg<int> segNumArg("y", "num_segments_per_image", "maximum number of 2D segments per image (longest)", false, L3D_DEF_MAX_NUM_SEGMENTS, "int");
    cmd.add(segNumArg);

    TCLAP::ValueArg<int> visibilityArg("v", "visibility_t", "minimum number of cameras to see a valid 3D line", false, L3D_DEF_MIN_VISIBILITY_T, "int");
    cmd.add(visibilityArg);

    TCLAP::ValueArg<bool> diffusionArg("d", "diffusion", "perform Replicator Dynamics Diffusion before clustering", false, L3D_DEF_PERFORM_RDD, "bool");
    cmd.add(diffusionArg);

    TCLAP::ValueArg<bool> loadArg("l", "load_and_store_flag", "load/store segments (recommended for big images)", false, L3D_DEF_LOAD_AND_STORE_SEGMENTS, "bool");
    cmd.add(loadArg);

    TCLAP::ValueArg<float> collinArg("r", "collinearity_t", "threshold for collinearity", false, L3D_DEF_COLLINEARITY_T, "float");
    cmd.add(collinArg);

    TCLAP::ValueArg<bool> cudaArg("g", "use_cuda", "use the GPU (CUDA)", false, true, "bool");
    cmd.add(cudaArg);

    TCLAP::ValueArg<bool> ceresArg("c", "use_ceres", "use CERES (for 3D line optimization)", false, L3D_DEF_USE_CERES, "bool");
    cmd.add(ceresArg);

    TCLAP::ValueArg<float> minBaselineArg("x", "min_image_baseline", "minimum baseline between matching images (world space)", false, L3D_DEF_MIN_BASELINE, "float");
    cmd.add(minBaselineArg);

    TCLAP::ValueArg<float> constRegDepthArg("z", "const_reg_depth", "use a constant regularization depth (only when sigma_p is metric!)", false, -1.0f, "float");
    cmd.add(constRegDepthArg);

    // read arguments
    cmd.parse(argc,argv);
    std::string inputFolder = inputArg.getValue().c_str();
    std::string nvmFile = nvmArg.getValue().c_str();

    // check if NVM file exists
    boost::filesystem::path nvm(nvmFile);
    if(!boost::filesystem::exists(nvm))
    {
        std::cerr << "NVM file " << nvmFile << " does not exist!" << std::endl;
        return -1;
    }

    bool use_full_image_path = false;
    if(inputFolder.length() == 0)
    {
        // parse input folder from .nvm file
        use_full_image_path = true;
        inputFolder = nvm.parent_path().string();
    }

    std::string outputFolder = outputArg.getValue().c_str();
    if(outputFolder.length() == 0)
        outputFolder = inputFolder+"/Line3D++/";

    int maxWidth = scaleArg.getValue();
    unsigned int neighbors = std::max(neighborArg.getValue(),2);
    bool diffusion = diffusionArg.getValue();
    bool loadAndStore = loadArg.getValue();
    float collinearity = collinArg.getValue();
    bool useGPU = cudaArg.getValue();
    bool useCERES = ceresArg.getValue();
    float epipolarOverlap = fmin(fabs(epipolarArg.getValue()),0.99f);
    float sigmaA = fabs(sigma_A_Arg.getValue());
    float sigmaP = sigma_P_Arg.getValue();
    float minBaseline = fabs(minBaselineArg.getValue());
    int kNN = knnArg.getValue();
    unsigned int maxNumSegments = segNumArg.getValue();
    unsigned int visibility_t = visibilityArg.getValue();
    float constRegDepth = constRegDepthArg.getValue();

    // create output directory
    boost::filesystem::path dir(outputFolder);
    boost::filesystem::create_directory(dir);

    // create Line3D++ object
    L3DPP::Line3D* Line3D = new L3DPP::Line3D(outputFolder,loadAndStore,maxWidth,
                                              maxNumSegments,true,useGPU);

    // read NVM file
    std::ifstream nvm_file;
    nvm_file.open(nvmFile.c_str());

    std::string nvm_line;
    std::getline(nvm_file,nvm_line); // ignore first line...
    std::getline(nvm_file,nvm_line); // ignore second line...

    // read number of images
    std::getline(nvm_file,nvm_line);
    std::stringstream nvm_stream(nvm_line);
    unsigned int num_cams;
    nvm_stream >> num_cams;

    if(num_cams == 0)
    {
        std::cerr << "No aligned cameras in NVM file!" << std::endl;
        return -1;
    }

    // read camera data (sequentially)
    std::vector<std::string> cams_imgFilenames(num_cams);
    std::vector<float> cams_focals(num_cams);
    std::vector<Eigen::Matrix3d> cams_rotation(num_cams);
    std::vector<Eigen::Vector3d> cams_translation(num_cams);
    std::vector<Eigen::Vector3d> cams_centers(num_cams);
    std::vector<float> cams_distortion(num_cams);
    for(unsigned int i=0; i<num_cams; ++i)
    {
        std::getline(nvm_file,nvm_line);

        // image filename
        std::string filename;

        // focal_length,quaternion,center,distortion
        double focal_length,qx,qy,qz,qw;
        double Cx,Cy,Cz,dist;

        nvm_stream.str("");
        nvm_stream.clear();
        nvm_stream.str(nvm_line);
        nvm_stream >> filename >> focal_length >> qw >> qx >> qy >> qz;
        nvm_stream >> Cx >> Cy >> Cz >> dist;

        cams_imgFilenames[i] = filename;
        cams_focals[i] = focal_length;
        cams_distortion[i] = dist;

        // rotation amd translation
        Eigen::Matrix3d R;
        R(0,0) = 1.0-2.0*qy*qy-2.0*qz*qz;
        R(0,1) = 2.0*qx*qy-2.0*qz*qw;
        R(0,2) = 2.0*qx*qz+2.0*qy*qw;

        R(1,0) = 2.0*qx*qy+2.0*qz*qw;
        R(1,1) = 1.0-2.0*qx*qx-2.0*qz*qz;
        R(1,2) = 2.0*qy*qz-2.0*qx*qw;

        R(2,0) = 2.0*qx*qz-2.0*qy*qw;
        R(2,1) = 2.0*qy*qz+2.0*qx*qw;
        R(2,2) = 1.0-2.0*qx*qx-2.0*qy*qy;

        Eigen::Vector3d C(Cx,Cy,Cz);
        cams_centers[i] = C;
        Eigen::Vector3d t = -R*C;

        cams_translation[i] = t;
        cams_rotation[i] = R;
    }

    // read number of images
    std::getline(nvm_file,nvm_line); // ignore line...
    std::getline(nvm_file,nvm_line);
    nvm_stream.str("");
    nvm_stream.clear();
    nvm_stream.str(nvm_line);
    unsigned int num_points;
    nvm_stream >> num_points;

    // read features (for image similarity calculation)
    std::vector<std::list<unsigned int> > cams_worldpointIDs(num_cams);
    std::vector<std::vector<float> > cams_worldpointDepths(num_cams);
    for(unsigned int i=0; i<num_points; ++i)
    {
        // 3D position
        std::getline(nvm_file,nvm_line);
        std::istringstream iss_point3D(nvm_line);
        double px,py,pz,colR,colG,colB;
        iss_point3D >> px >> py >> pz;
        iss_point3D >> colR >> colG >> colB;
        Eigen::Vector3d pos3D(px,py,pz);

        // measurements
        unsigned int num_views;
        iss_point3D >> num_views;

        unsigned int camID,siftID;
        float posX,posY;
        for(unsigned int j=0; j<num_views; ++j)
        {
            iss_point3D >> camID >> siftID;
            iss_point3D >> posX >> posY;
            cams_worldpointIDs[camID].push_back(i);

            cams_worldpointDepths[camID].push_back((pos3D-cams_centers[camID]).norm());
        }
    }
    nvm_file.close();

    // load images (parallel)
#ifdef L3DPP_OPENMP
    #pragma omp parallel for
#endif //L3DPP_OPENMP
    for(unsigned int i=0; i<num_cams; ++i)
    {
        if(cams_worldpointDepths[i].size() > 0)
        {
            // parse filename
            std::string fname = cams_imgFilenames[i];
            boost::filesystem::path img_path(fname);

            // load image
            cv::Mat image;
            if(use_full_image_path)
                image = cv::imread(inputFolder+"/"+fname,CV_LOAD_IMAGE_GRAYSCALE);
            else
                image = cv::imread(inputFolder+"/"+img_path.filename().string(),CV_LOAD_IMAGE_GRAYSCALE);

            // setup intrinsics
            float px = float(image.cols)/2.0f;
            float py = float(image.rows)/2.0f;
            float f = cams_focals[i];

            Eigen::Matrix3d K = Eigen::Matrix3d::Zero();
            K(0,0) = f;
            K(1,1) = f;
            K(0,2) = px;
            K(1,2) = py;
            K(2,2) = 1.0;

            // undistort (if necessary)
            float d = cams_distortion[i];

            cv::Mat img_undist;
            if(fabs(d) > L3D_EPS)
            {
                // undistorting
                Eigen::Vector3d radial(-d,0.0,0.0);
                Eigen::Vector2d tangential(0.0,0.0);
                Line3D->undistortImage(image,img_undist,radial,tangential,K);
            }
            else
            {
                // already undistorted
                img_undist = image;
            }

            // median point depth
            std::sort(cams_worldpointDepths[i].begin(),cams_worldpointDepths[i].end());
            size_t med_pos = cams_worldpointDepths[i].size()/2;
            float med_depth = cams_worldpointDepths[i].at(med_pos);

            // add to system
            Line3D->addImage(i,img_undist,K,cams_rotation[i],
                             cams_translation[i],
                             med_depth,cams_worldpointIDs[i]);
        }
    }

    // match images
    Line3D->matchImages(sigmaP,sigmaA,neighbors,epipolarOverlap,
                        minBaseline,kNN,constRegDepth);

    // compute result
    Line3D->reconstruct3Dlines(visibility_t,diffusion,collinearity,useCERES);

    // save end result
    std::vector<L3DPP::FinalLine3D> result;
    Line3D->get3Dlines(result);

    // save as STL
    Line3D->saveResultAsSTL(outputFolder);
    // save as OBJ
    Line3D->saveResultAsOBJ(outputFolder);
    // save as TXT
    Line3D->save3DLinesAsTXT(outputFolder);

    // cleanup
    delete Line3D;
}
示例#6
0
void QElipseItem::SetPattern(int nPATTERN) //set the line pattern
{
    nPatternType = nPATTERN;
    QRectF nrect=rect();
    QLinearGradient gradient(nrect.topLeft(),nrect.bottomRight());
    QRadialGradient radial(nrect.center(),nrect.width()/2,nrect.center());
    // Conical.setSpread(QGradient::ReflectSpread);
    gradient.setSpread(QGradient::PadSpread);//	RepeatSpread

    QBrush br=brush();
    br.setColor(nFrontColor); //设置前景色即样式颜色

    switch(nPatternType)
    {
    case 0:br.setStyle(Qt::NoBrush);break;
    case 1:br.setColor(nBackColor); br.setStyle(Qt::SolidPattern);break;
//    case 2:br.setStyle(Qt::Dense1Pattern);break;
//    case 3:br.setStyle(Qt::Dense2Pattern);break;
//    case 4:br.setStyle(Qt::Dense3Pattern);break;
//    case 5:br.setStyle(Qt::Dense4Pattern);break;
//    case 6:br.setStyle(Qt::Dense5Pattern);break;
//    case 7:br.setStyle(Qt::Dense6Pattern);break;
//    case 8:br.setStyle(Qt::Dense7Pattern);break;

//    case 9:br.setStyle(Qt::HorPattern);break;//setBrush(Qt::HorPattern);break;
//    case 10:br.setStyle(Qt::VerPattern);break;
//    case 11:br.setStyle(Qt::CrossPattern);break;

//    case 12:br.setStyle(Qt::BDiagPattern);break;
//    case 13:br.setStyle(Qt::FDiagPattern);break;
//    case 14:br.setStyle(Qt::DiagCrossPattern);break;

    case 2: //横向过度
        gradient.setStart(nrect.bottomLeft());
        gradient.setColorAt(0,nFrontColor);
        gradient.setColorAt(1,nBackColor);
        this->setBrush(gradient);
        break;
    case 3: //横向对称过度
        gradient.setStart(nrect.bottomLeft());
        gradient.setColorAt(0,nFrontColor);
        gradient.setColorAt(0.5,nBackColor);
        gradient.setColorAt(1,nFrontColor);
        this->setBrush(gradient);
        break;
    case 4: //纵向过度
        gradient.setStart(nrect.topRight());
        gradient.setColorAt(0,nFrontColor);
        gradient.setColorAt(1,nBackColor);
        this->setBrush(gradient);
        break;
    case 5: //纵向对称过度
        gradient.setStart(nrect.topRight());
        gradient.setColorAt(0,nFrontColor);
        gradient.setColorAt(0.5,nBackColor);
        gradient.setColorAt(1,nFrontColor);
        this->setBrush(gradient);
        break;
    case 6: //斜上过度
        gradient.setColorAt(0,nFrontColor);
        gradient.setColorAt(1,nBackColor);
        this->setBrush(gradient);
        break;
    case 7: //斜上对称过度
        gradient.setColorAt(0,nFrontColor);
        gradient.setColorAt(0.5,nBackColor);
        gradient.setColorAt(1,nFrontColor);
        this->setBrush(gradient);
        break;
    case 8: //斜下过度
        gradient.setStart(nrect.bottomLeft());
        gradient.setFinalStop(nrect.topRight());
        gradient.setColorAt(0,nBackColor);
        gradient.setColorAt(1,nFrontColor);
        this->setBrush(gradient);
        break;
    case 9: //斜下对称过度
        gradient.setStart(nrect.bottomLeft());
        gradient.setFinalStop(nrect.topRight());
        gradient.setColorAt(0,nFrontColor);
        gradient.setColorAt(0.5,nBackColor);
        gradient.setColorAt(1,nFrontColor);
        this->setBrush(gradient);
        break;
    case 10: //右上角辐射
        gradient.setStart(nrect.topRight());
        gradient.setFinalStop(nrect.bottomLeft());
        gradient.setColorAt(0,nBackColor);
        gradient.setColorAt(1,nFrontColor);
        this->setBrush(gradient);
        break;
    case 11: //左上角辐射
        gradient.setColorAt(0,nBackColor);
        gradient.setColorAt(1, nFrontColor);
        this->setBrush(gradient);
        break;
    case 12: //中心辐射
        radial.setColorAt(0,nBackColor);
        radial.setColorAt(1,nFrontColor);
        this->setBrush(radial);
        break;
    case 13: //待操作
        radial.setFocalPoint(nrect.x(),nrect.center().y());
        radial.setColorAt(0,nBackColor);
        radial.setColorAt(1,nFrontColor);
        this->setBrush(radial);
        break;
    case 27://kong
        radial.setFocalPoint(nrect.center().x(),nrect.center().y());
        radial.setColorAt(0,QColor(255,0,0,0));
        radial.setColorAt(nPropor,QColor(255,0,0,0));
        radial.setColorAt(nPropor + 0.01,nBackColor);
        radial.setColorAt(1,nBackColor);
        this->setBrush(radial);
        break;
    default:
        break;
    }
    if(0 == nPatternType || 1 == nPatternType)
    {
        setBrush(br);
    }
}
示例#7
0
void Power::paintEvent(QPaintEvent *ev)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setWindow(wRect);


    //先画一个外框方框
    painter.setPen(Qt::NoPen);
 //   painter.setBrush(QColor(255,255,255,0));
  //  painter.drawRoundedRect(wRect,wRect.height()/2,wRect.height()/2);

    //画开启框左右圆弧
    painter.setBrush(radialON);
    painter.drawEllipse(pieON,this->pieR,this->pieR);
    //画开启框
    painter.setBrush(linearON);
    painter.drawRect(rect);


    //画开启文字
    painter.setPen(QPen(Qt::white,1,Qt::SolidLine,
                        Qt::RoundCap, Qt::RoundJoin));
    painter.setFont(this->font());
    painter.drawText(QRect(rect.x() + pieR,rect.y(),rect.width() - pieR ,rect.height()),
                    Qt::AlignCenter,textON());
    painter.setPen(Qt::NoPen);
    //画关闭圆弧
    painter.setBrush(radialOFF);
    painter.drawEllipse(pieOFF,pieR,pieR);
    //画关闭框
    QRect ONRect(rect.x(),rect.y(),rd,rect.height());
    painter.setBrush(linearOFF);
    painter.drawRect(ONRect);

    //画关闭文字
    painter.setPen(QPen(Qt::white,1,Qt::SolidLine,
                       Qt::RoundCap, Qt::RoundJoin));
    painter.setFont(this->font());
    painter.drawText(QRect(rect.x(),rect.y(),rd - pieR,rect.height()),
                     Qt::AlignCenter,textOFF());

    painter.setPen(Qt::NoPen);
    if(hover)
    {
        painter.setBrush(QColor(0, 0, 0, 50));
        painter.drawRoundedRect(wRect,round,round);
    }
    //画开关圆头
    QPointF pieONr(pieOFF.x() + rd,pieOFF.y());
    //圆头的渐变颜色
    QRadialGradient radial(pieONr,wRect.height() / 2 - 1);
    radial.setColorAt(0,QColor(124, 238, 255));
    radial.setColorAt(0.8,QColor(124, 238, 255));
    radial.setColorAt(1,QColor(0, 170, 255));
    painter.setBrush(radial);

    painter.drawEllipse(pieONr,wRect.height() / 2 - 1,wRect.height() / 2  - 1);
    ev->accept();

}
void AttitudeIndicator::createCard(float w, float h){
    // Init dimensions
    double size = 0.85;
    double targetW = qMin(w*size,h*size);
    double targetH = targetW*0.70;
    double realH = targetH*1.3;
    double midX = targetW / 2.0;
    double midY = targetH / 2.0;

    // Create image
    QImage _cardImage = QImage(QSize(targetW,realH), QImage::Format_ARGB32);
    _cardImage.fill(0x00ff0000);

    QPainter p;
    p.begin(&_cardImage);
    setupPainter(&p);
    p.translate(0,(realH-targetH)/2.0);

    // Shadow
    p.save(); {
        double shadowSize = 0.86;
        p.setPen(Qt::NoPen);
        double shadowRH = realH/2.0*shadowSize;
        QRadialGradient radial(QPointF(midX, midY), shadowRH);
        p.scale(1.8,1.0);
        p.translate(-midX*0.4,0);
        radial.setColorAt(0.6, Qt::black); //I want the center to be black
        radial.setColorAt(1, Qt::transparent); //I want the sides to be white
        p.setBrush(QBrush(radial));
        p.setOpacity(0.4);
        p.drawEllipse(QPointF(midX,midY),targetW/2.0*0.8,shadowRH);
    } p.restore();

    // Draw upper horizon
    QLinearGradient gradient(5, midY-5,midX,midY-5);
    gradient.setSpread(QGradient::ReflectSpread);
    gradient.setColorAt(0, ATTITUDE_COLOR_BLUE_DARK);
    gradient.setColorAt(1, ATTITUDE_COLOR_BLUE_LIGHT);
    QBrush gbrush(gradient);
    p.setPen(QPen(QColor(0,0,0,50),targetW*0.004));
    p.setBrush(gbrush);
    p.drawChord(0,0,targetW, targetH, 0, 180*16);

    // Draw lower ground
    gradient.setColorAt(0, ATTITUDE_COLOR_BROWN_DARK);
    gradient.setColorAt(1, ATTITUDE_COLOR_BROWN_LIGHT);
    QBrush gbrush2(gradient);
    p.setBrush(gbrush2);
    p.drawChord(0,0, targetW, targetH, 180*16, 180*16);

    p.save(); {
        // Original drawing code was 510x360, so we to keep that code we need to scale for it
        double origW = 510.0;
        double origH = 360;
        double origMidX = origW / 2.0;
        double origMidY = origH / 2.0;
        double scale = targetW/origW;
        p.scale(scale,scale);

        // Draw horizon and angle cues
        p.setPen(QPen(Qt::white, 7, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
        p.drawLine(0,origMidY,origW-1,origMidY);
        p.setPen(QPen(Qt::white, 5, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
        float sl = origMidX*0.72;
        float ll = origMidX*0.84;
        p.drawLine(origMidX,origMidY,origMidX+cos(30./180.*3.14159)*ll,origMidY+sin(30./180.*3.14159)*ll);
        p.drawLine(origMidX,origMidY,origMidX+cos(60./180.*3.14159)*sl,origMidY+sin(60./180.*3.14159)*sl);
        p.drawLine(origMidX,origMidY,origMidX-cos(30./180.*3.14159)*ll,origMidY+sin(30./180.*3.14159)*ll);
        p.drawLine(origMidX,origMidY,origMidX-cos(60./180.*3.14159)*sl,origMidY+sin(60./180.*3.14159)*sl);

        // Draw pitch up and down lines
        p.setPen(QPen(QColor(0,0,15), 5, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
        p.drawLine(origMidX-45, origMidY-60*pitchPixelsPerDegree, origMidX+45,origMidY-60*pitchPixelsPerDegree);
        p.drawLine(origMidX-24, origMidY-30*pitchPixelsPerDegree, origMidX+24,origMidY-30*pitchPixelsPerDegree);
        p.setPen(QPen(Qt::white, 5, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
        p.drawLine(origMidX-35, origMidY+80*pitchPixelsPerDegree, origMidX+35,origMidY+80*pitchPixelsPerDegree);
        p.drawLine(origMidX-17, origMidY+46*pitchPixelsPerDegree, origMidX+17,origMidY+46*pitchPixelsPerDegree);

    } p.restore();

    // Save as pixmap
    p.end();
    _card = QPixmap::fromImage(_cardImage, Qt::AutoColor);
}
void AttitudeIndicator::createFrame(float w, float h){
    // Init dimensions
    double origW = 600.0;
    double targetW = qMin(w,h);
    double targetH = targetW;

    // Create image
    QImage _frameImage = QImage(QSize(targetW,targetH), QImage::Format_ARGB32);
    _frameImage.fill(0x00ff0000);

    // Init painter and scale to the original drawing size at 600x600
    QPainter p;
    p.begin(&_frameImage);
    setupPainter(&p);
    double scale = targetW/origW;
    p.scale(scale,scale);
    p.translate(300, 300);

    // Dimensions
    uint midx, midy, width, height;
    width = _frameImage.width();
    midx = width/2;
    height = _frameImage.height();
    midy = height/2;

    // Shadow
    double shadowSize = 0.8;
    QPainterPath pathShadow;
    pathShadow.moveTo(240,0);
    pathShadow.lineTo(300,0);
    pathShadow.arcTo(-290,-290,580,580, 0, 360);
    pathShadow.lineTo(-240,0);
    pathShadow.arcTo(-240*shadowSize,-240*shadowSize,480*shadowSize,480*shadowSize, 0, 360);
    p.setPen(Qt::NoPen);
    QRadialGradient radial(QPointF(0, 0), 290);
    radial.setColorAt(0.74, Qt::transparent); //I want the center to be black
    radial.setColorAt(1, Qt::black); //I want the sides to be white
    p.setBrush(QBrush(radial));
    p.drawPath(pathShadow);

    // Upper half
    QPainterPath pathTop;
    pathTop.moveTo(240,0);
    pathTop.lineTo(300,0);
    pathTop.arcTo(-300,-300,600,600, 0, 180);
    pathTop.lineTo(-240,0);
    pathTop.arcTo(-240,-240,480,480, 180, -180);
    p.setPen(QPen(QColor(0, 0, 0), 4, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
    p.setBrush(SKYBLUE);
    p.drawPath(pathTop);
     
    // Lower half
    QPainterPath pathBottom;
    pathBottom.moveTo(240,0);
    pathBottom.lineTo(300,0);
    pathBottom.arcTo(-300,-300,600,600, 0, -180);
    pathBottom.lineTo(-240,0);
    pathBottom.arcTo(-240,-240,480,480, 180, 180);
    p.setPen(QPen(QColor(0, 0, 0), 4, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
    p.setBrush(ATTITUDE_COLOR_BROWN_DARK);
    p.drawPath(pathBottom);

    // Line markings
    double l1 = 243.0;
    double l2 = 298.0;
    p.setPen(QPen(Qt::white, 5, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
    for(int i=70; i<=110; i+=10){
        p.drawLine(l1*cos(float(i)/180.*M_PI),-l1*sin(float(i)/180.*M_PI),
                   l2*cos(float(i)/180.*M_PI),-l2*sin(float(i)/180.*M_PI));
    }
    p.setPen(QPen(Qt::white, 10, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
    for(int i=0; i<=180; i+=30){
        p.drawLine(l1*cos(float(i)/180.*M_PI),-l1*sin(float(i)/180.*M_PI),
                   l2*cos(float(i)/180.*M_PI),-l2*sin(float(i)/180.*M_PI));
    }

    // Save as pixmap
    p.end();
    _frame = QPixmap::fromImage(_frameImage, Qt::AutoColor);
}