void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
                                   const SkMatrix* matrix,
                                   const GrRect* srcRects[],
                                   const SkMatrix* srcMatrices[]) {

    GrVertexLayout layout = 0;
    GrDrawState::AutoColorRestore acr;
    GrColor color = this->drawState()->getColor();

    // Using per-vertex colors allows batching across colors. (A lot of rects in a row differing
    // only in color is a common occurrence in tables). However, having per-vertex colors disables
    // blending optimizations because we don't know if the color will be solid or not. These
    // optimizations help determine whether coverage and color can be blended correctly when
    // dual-source blending isn't available. This comes into play when there is coverage. If colors
    // were a stage it could take a hint that every vertex's color will be opaque.
    if (this->getCaps().dualSourceBlendingSupport() ||
        this->getDrawState().hasSolidCoverage(this->getGeomSrc().fVertexLayout)) {
        layout |= GrDrawState::kColor_VertexLayoutBit;;
        // We set the draw state's color to white here. This is done so that any batching performed
        // in our subclass's onDraw() won't get a false from GrDrawState::op== due to a color
        // mismatch. TODO: Once vertex layout is owned by GrDrawState it should skip comparing the
        // constant color in its op== when the kColor layout bit is set and then we can remove this.
        acr.set(this->drawState(), 0xFFFFFFFF);
    }

    uint32_t explicitCoordMask = 0;
    if (NULL != srcRects) {
        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
            int numTC = 0;
            if (NULL != srcRects[s]) {
                layout |= GrDrawState::StageTexCoordVertexLayoutBit(s, numTC);
                ++numTC;
                explicitCoordMask |= (1 << s);
            }
        }
    }

    AutoReleaseGeometry geo(this, layout, 4, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return;
    }

    // Go to device coords to allow batching across matrix changes
    SkMatrix combinedMatrix;
    if (NULL != matrix) {
        combinedMatrix = *matrix;
    } else {
        combinedMatrix.reset();
    }
    combinedMatrix.postConcat(this->drawState()->getViewMatrix());
    // When the caller has provided an explicit source rects for a stage then we don't want to
    // modify that stage's matrix. Otherwise if the effect is generating its source rect from
    // the vertex positions then we have to account for the view matrix change.
    GrDrawState::AutoDeviceCoordDraw adcd(this->drawState(), explicitCoordMask);
    if (!adcd.succeeded()) {
        return;
    }

    int stageOffsets[GrDrawState::kNumStages], colorOffset;
    int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets,
                                                         &colorOffset, NULL, NULL);

    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
    combinedMatrix.mapPointsWithStride(geo.positions(), vsize, 4);

    SkRect devBounds;
    // since we already computed the dev verts, set the bounds hint. This will help us avoid
    // unnecessary clipping in our onDraw().
    get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds);

    for (int i = 0; i < GrDrawState::kNumStages; ++i) {
        if (explicitCoordMask & (1 << i)) {
            GrAssert(0 != stageOffsets[i]);
            GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
                                                stageOffsets[i]);
            coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
                               srcRects[i]->fRight, srcRects[i]->fBottom,
                               vsize);
            if (NULL != srcMatrices && NULL != srcMatrices[i]) {
                srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
            }
        } else {
            GrAssert(0 == stageOffsets[i]);
        }
    }

    if (colorOffset >= 0) {
        GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + colorOffset);
        for (int i = 0; i < 4; ++i) {
            *vertColor = color;
            vertColor = (GrColor*) ((intptr_t) vertColor + vsize);
        }
    }

    this->setIndexSourceToBuffer(fGpu->getQuadIndexBuffer());
    this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
}
Example #2
0
	bool RootPanel::render()
	{
		return render( geo() );
	}
Example #3
0
	void RootPanel::MyHook::_requestRender()
	{
		if( m_pRoot->m_bVisible )
			m_pRoot->addDirtyPatch( geo() );
	}
Example #4
0
 static QPoint pos(QWidget *widget) { return geo(widget).topLeft(); }
Example #5
0
 static QSize size(QWidget *widget) { return geo(widget).size(); }
Example #6
0
void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect,
                                     const SkMatrix* matrix,
                                     const SkRect* localRect,
                                     const SkMatrix* localMatrix) {
    GrDrawState::AutoColorRestore acr;

    GrDrawState* drawState = this->drawState();

    GrColor color = drawState->getColor();

    int colorOffset, localOffset;
    set_vertex_attributes(drawState,
                   this->caps()->dualSourceBlendingSupport() || drawState->hasSolidCoverage(),
                   NULL != localRect,
                   &colorOffset, &localOffset);
    if (colorOffset >= 0) {
        // We set the draw state's color to white here. This is done so that any batching performed
        // in our subclass's onDraw() won't get a false from GrDrawState::op== due to a color
        // mismatch. TODO: Once vertex layout is owned by GrDrawState it should skip comparing the
        // constant color in its op== when the kColor layout bit is set and then we can remove
        // this.
        acr.set(drawState, 0xFFFFFFFF);
    }

    AutoReleaseGeometry geo(this, 4, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return;
    }

    // Go to device coords to allow batching across matrix changes
    SkMatrix combinedMatrix;
    if (NULL != matrix) {
        combinedMatrix = *matrix;
    } else {
        combinedMatrix.reset();
    }
    combinedMatrix.postConcat(drawState->getViewMatrix());
    // When the caller has provided an explicit source rect for a stage then we don't want to
    // modify that stage's matrix. Otherwise if the effect is generating its source rect from
    // the vertex positions then we have to account for the view matrix change.
    GrDrawState::AutoViewMatrixRestore avmr;
    if (!avmr.setIdentity(drawState)) {
        return;
    }

    size_t vsize = drawState->getVertexSize();

    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
    combinedMatrix.mapPointsWithStride(geo.positions(), vsize, 4);

    SkRect devBounds;
    // since we already computed the dev verts, set the bounds hint. This will help us avoid
    // unnecessary clipping in our onDraw().
    get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds);

    if (localOffset >= 0) {
        SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + localOffset);
        coords->setRectFan(localRect->fLeft, localRect->fTop,
                           localRect->fRight, localRect->fBottom,
                            vsize);
        if (NULL != localMatrix) {
            localMatrix->mapPointsWithStride(coords, vsize, 4);
        }
    }

    if (colorOffset >= 0) {
        GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + colorOffset);
        for (int i = 0; i < 4; ++i) {
            *vertColor = color;
            vertColor = (GrColor*) ((intptr_t) vertColor + vsize);
        }
    }

    this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
    this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);

    // to ensure that stashing the drawState ptr is valid
    SkASSERT(this->drawState() == drawState);
}
void GrAARectRenderer::strokeAARect(GrGpu* gpu,
                                    GrDrawTarget* target,
                                    const GrRect& devRect,
                                    const GrVec& devStrokeSize,
                                    bool useVertexCoverage) {
    const SkScalar& dx = devStrokeSize.fX;
    const SkScalar& dy = devStrokeSize.fY;
    const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf);
    const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf);

    SkScalar spare;
    {
        SkScalar w = devRect.width() - dx;
        SkScalar h = devRect.height() - dy;
        spare = GrMin(w, h);
    }

    if (spare <= 0) {
        GrRect r(devRect);
        r.inset(-rx, -ry);
        this->fillAARect(gpu, target, r, useVertexCoverage);
        return;
    }
    GrVertexLayout layout = aa_rect_layout(useVertexCoverage);
    size_t vsize = GrDrawState::VertexSize(layout);

    GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return;
    }
    GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu);
    if (NULL == indexBuffer) {
        GrPrintf("Failed to create index buffer!\n");
        return;
    }

    intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());

    // We create vertices for four nested rectangles. There are two ramps from 0 to full
    // coverage, one on the exterior of the stroke and the other on the interior.
    // The following pointers refer to the four rects, from outermost to innermost.
    GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
    GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);
    GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize);
    GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize);

    set_inset_fan(fan0Pos, vsize, devRect,
                  -rx - SK_ScalarHalf, -ry - SK_ScalarHalf);
    set_inset_fan(fan1Pos, vsize, devRect,
                  -rx + SK_ScalarHalf, -ry + SK_ScalarHalf);
    set_inset_fan(fan2Pos, vsize, devRect,
                  rx - SK_ScalarHalf,  ry - SK_ScalarHalf);
    set_inset_fan(fan3Pos, vsize, devRect,
                  rx + SK_ScalarHalf,  ry + SK_ScalarHalf);

    // The outermost rect has 0 coverage
    verts += sizeof(GrPoint);
    for (int i = 0; i < 4; ++i) {
        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
    }

    // The inner two rects have full coverage
    GrColor innerColor;
    if (useVertexCoverage) {
        innerColor = 0xffffffff;
    } else {
        innerColor = target->getDrawState().getColor();
    }
    verts += 4 * vsize;
    for (int i = 0; i < 8; ++i) {
        *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
    }

    // The innermost rect has full coverage
    verts += 8 * vsize;
    for (int i = 0; i < 4; ++i) {
        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
    }

    target->setIndexSourceToBuffer(indexBuffer);
    target->drawIndexed(kTriangles_GrPrimitiveType,
                        0, 0, 16, aaStrokeRectIndexCount());
}
static osg::Node* readImageStream(const std::string& file_name, osg::Vec3& p, float desired_height, osgDB::Options* options)
{
    osg::ref_ptr<osg::Object> obj = osgDB::readRefObjectFile(file_name, options);
    osg::ref_ptr<osg::Texture> tex = dynamic_cast<osg::Texture*>(obj.get());
    osg::Geometry* geo(NULL);
    float w(0);

    if (!tex)
    {
        osg::ref_ptr<osg::ImageStream> img_stream = dynamic_cast<osg::ImageStream*>(obj.get());

        // try readImageFile if readObjectFile failed
        if (!img_stream)
        {
            img_stream = osgDB::readRefFile<osg::ImageStream>(file_name, options);
        }

        if (img_stream)
        {
            tex = new osg::Texture2D(img_stream.get());
            tex->setResizeNonPowerOfTwoHint(false);

        }
    }

    // create textured quad
    if(tex)
    {
        osg::Geode* geode = new osg::Geode();

        osg::ref_ptr<osg::ImageStream> img = dynamic_cast<osg::ImageStream*>(tex->getImage(0));
        if (img)
        {
            w = (img->t() > 0) ? img->s() * desired_height / img->t() : 0;

            osgText::Text* text = new osgText::Text();
            text->setFont("arial.ttf");
            text->setDataVariance(osg::Object::DYNAMIC);
            text->setUpdateCallback(new ImageStreamStateCallback(text, img.get()));
            text->setCharacterSize(24);
            text->setPosition(p + osg::Vec3(10,-10,10));
            text->setAxisAlignment(osgText::TextBase::XZ_PLANE);
            geode->addDrawable (text);
        }

        if (w == 0)
        {
            // hmm, imagestream with no width?
            w = desired_height * 16 / 9.0f;
        }
        float tex_s = (tex->getTextureTarget() == GL_TEXTURE_2D) ? 1 : img->s();
        float tex_t = (tex->getTextureTarget() == GL_TEXTURE_2D) ? 1 : img->t();

        if (img->getOrigin() == osg::Image::TOP_LEFT)
            geo = osg::createTexturedQuadGeometry(p, osg::Vec3(w, 0, 0), osg::Vec3(0, 0, desired_height), 0, tex_t, tex_s, 0);
        else
            geo = osg::createTexturedQuadGeometry(p, osg::Vec3(w, 0, 0), osg::Vec3(0, 0, desired_height), 0, 0, tex_s, tex_t);

        geode->addDrawable(geo);

        geo->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex.get());

        osg::Vec4Array* colors = new osg::Vec4Array();
        colors->push_back(osg::Vec4(0.7, 0.7, 0.7, 1));

        geo->setColorArray(colors, osg::Array::BIND_OVERALL);

        p[0] += w + 10;

        img->addDimensionsChangedCallback(new MyDimensionsChangedCallback(tex.get(), geo));

        return geode;
    }
    else
    {
        std::cout << "could not read file from " << file_name << std::endl;
        return NULL;
    }

    return NULL;
}
Example #9
0
osg::ref_ptr<osg::Node> get(const ImageVec_t& images)
{
    osg::ref_ptr<osg::Group> rv( new osg::Group() );

    for ( const auto& image : images )
    {
        // here we create a quad that will be texture mapped with the image
        osg::ref_ptr<osg::Vec3Array> quad( new osg::Vec3Array() );
        quad->push_back( image.corners[0] );
        quad->push_back( image.corners[1] );
        quad->push_back( image.corners[2] );
        quad->push_back( image.corners[3] );
        osg::ref_ptr<osg::Geometry> geo( new osg::Geometry() );
        geo->setVertexArray( quad );

        // here we create a drawing elelment to draw on
        osg::ref_ptr<osg::DrawElementsUInt>
            primitiveSet( new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0) );
        primitiveSet->push_back( 0 );
        primitiveSet->push_back( 1 );
        primitiveSet->push_back( 2 );
        primitiveSet->push_back( 3 );
        geo->addPrimitiveSet( primitiveSet );

        // the texture mappings
        osg::ref_ptr<osg::Vec2Array> texCoords( new osg::Vec2Array(4) );
        (*texCoords)[3].set( 0.0f, 0.0f );
        (*texCoords)[2].set( 1.0f, 0.0f );
        (*texCoords)[1].set( 1.0f, 1.0f );
        (*texCoords)[0].set( 0.0f, 1.0f );
        geo->setTexCoordArray( 0, texCoords );

        // now create the goede to hold our created geometry
        osg::ref_ptr<osg::Geode> geode( new osg::Geode() );
        geode->addDrawable( geo );

        // create the texture for the image
        osg::ref_ptr<osg::Texture2D> texture( new osg::Texture2D() );
        texture->setResizeNonPowerOfTwoHint(false);
        texture->setDataVariance(osg::Object::STATIC);
        texture->setImage( image.image );
        texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
        texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);

        // put this in decal mode
        osg::ref_ptr<osg::TexEnv> decalTexEnv( new osg::TexEnv() );
        decalTexEnv->setMode(osg::TexEnv::DECAL);

        // set the state set, lighting and such, so we actually display the image
        osg::ref_ptr<osg::StateSet> stateSet( geode->getOrCreateStateSet() );
        stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
        stateSet->setTextureAttribute(0, decalTexEnv);
        stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
        geo->setStateSet(stateSet);

        // turn off any color binding - we want to use the texture
        geo->setColorBinding(osg::Geometry::BIND_OFF);

        // add this image and continue
        rv->addChild(geode);
    }

    return rv;
};
void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
                                   const SkMatrix* matrix,
                                   const GrRect* srcRects[],
                                   const SkMatrix* srcMatrices[]) {

    GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
    GrAssert(!(fDraws.empty() && fCurrQuad));
    GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));

    GrDrawState* drawState = this->drawState();

    // if we have a quad IB then either append to the previous run of
    // rects or start a new run
    if (fMaxQuads) {

        bool appendToPreviousDraw = false;
        GrVertexLayout layout = GetRectVertexLayout(srcRects);

        // Batching across colors means we move the draw color into the
        // rect's vertex colors to allow greater batching (a lot of rects
        // in a row differing only in color is a common occurence in tables).
        bool batchAcrossColors = true;
        if (!this->getCaps().dualSourceBlendingSupport()) {
            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
                if (this->getDrawState().isStageEnabled(s)) {
                    // We disable batching across colors when there is a texture
                    // present because (by pushing the the color to the vertices)
                    // Ganesh loses track of the rect's opacity. This, in turn, can
                    // cause some of the blending optimizations to be disabled. This
                    // becomes a huge problem on some of the smaller devices where
                    // shader derivatives and dual source blending aren't supported.
                    // In those cases paths are often drawn to a texture and then
                    // drawn as a texture (using this method). Because dual source
                    // blending is disabled (and the blend optimizations are short
                    // circuited) some of the more esoteric blend modes can no longer
                    // be supported.
                    // TODO: add tracking of batchAcrossColors's opacity
                    batchAcrossColors = false;
                    break;
                }
            }
        }

        if (batchAcrossColors) {
            layout |= GrDrawState::kColor_VertexLayoutBit;
        }

        AutoReleaseGeometry geo(this, layout, 4, 0);
        if (!geo.succeeded()) {
            GrPrintf("Failed to get space for vertices!\n");
            return;
        }
        SkMatrix combinedMatrix = drawState->getViewMatrix();
        // We go to device space so that matrix changes allow us to concat
        // rect draws. When the caller has provided explicit source rects
        // then we don't want to modify the stages' matrices. Otherwise
        // we have to account for the view matrix change in the stage
        // matrices.
        uint32_t explicitCoordMask = 0;
        if (srcRects) {
            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
                if (srcRects[s]) {
                    explicitCoordMask |= (1 << s);
                }
            }
        }
        GrDrawState::AutoDeviceCoordDraw adcd(this->drawState(), explicitCoordMask);
        if (!adcd.succeeded()) {
            return;
        }
        if (NULL != matrix) {
            combinedMatrix.preConcat(*matrix);
        }

        SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices,
                        this->getDrawState().getColor(), layout, geo.vertices());

        // Now that the paint's color is stored in the vertices set it to
        // white so that the following code can batch all the rects regardless
        // of paint color
        GrDrawState::AutoColorRestore acr(this->drawState(),
                                          batchAcrossColors ? SK_ColorWHITE
                                                            : this->getDrawState().getColor());

        // we don't want to miss an opportunity to batch rects together
        // simply because the clip has changed if the clip doesn't affect
        // the rect.
        bool disabledClip = false;

        if (drawState->isClipState()) {

            GrRect devClipRect;
            bool isIntersectionOfRects = false;
            const GrClipData* clip = this->getClip();
            clip->fClipStack->getConservativeBounds(-clip->fOrigin.fX,
                                                    -clip->fOrigin.fY,
                                                    drawState->getRenderTarget()->width(),
                                                    drawState->getRenderTarget()->height(),
                                                    &devClipRect,
                                                    &isIntersectionOfRects);

            if (isIntersectionOfRects) {
                // If the clip rect touches the edge of the viewport, extended it
                // out (close) to infinity to avoid bogus intersections.
                // We might consider a more exact clip to viewport if this
                // conservative test fails.
                const GrRenderTarget* target = drawState->getRenderTarget();
                if (0 >= devClipRect.fLeft) {
                    devClipRect.fLeft = SK_ScalarMin;
                }
                if (target->width() <= devClipRect.fRight) {
                    devClipRect.fRight = SK_ScalarMax;
                }
                if (0 >= devClipRect.top()) {
                    devClipRect.fTop = SK_ScalarMin;
                }
                if (target->height() <= devClipRect.fBottom) {
                    devClipRect.fBottom = SK_ScalarMax;
                }
                int stride = GrDrawState::VertexSize(layout);
                bool insideClip = true;
                for (int v = 0; v < 4; ++v) {
                    const GrPoint& p = *GrDrawState::GetVertexPoint(geo.vertices(), v, stride);
                    if (!devClipRect.contains(p)) {
                        insideClip = false;
                        break;
                    }
                }
                if (insideClip) {
                    drawState->disableState(GrDrawState::kClip_StateBit);
                    disabledClip = true;
                }
            }
        }

        if (!this->needsNewClip() &&
            !this->needsNewState() &&
            fCurrQuad > 0 &&
            fCurrQuad < fMaxQuads &&
            layout == fLastRectVertexLayout) {

            int vsize = GrDrawState::VertexSize(layout);

            Draw& lastDraw = fDraws.back();

            GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
            GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
            GrAssert(0 == lastDraw.fVertexCount % 4);
            GrAssert(0 == lastDraw.fIndexCount % 6);
            GrAssert(0 == lastDraw.fStartIndex);

            GeometryPoolState& poolState = fGeoPoolStateStack.back();

            appendToPreviousDraw =
                kDraw_Cmd == fCmds.back() &&
                lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
                (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;

            if (appendToPreviousDraw) {
                lastDraw.fVertexCount += 4;
                lastDraw.fIndexCount += 6;
                fCurrQuad += 1;
                // we reserved above, so we should be the first
                // use of this vertex reservation.
                GrAssert(0 == poolState.fUsedPoolVertexBytes);
                poolState.fUsedPoolVertexBytes = 4 * vsize;
            }
        }
        if (!appendToPreviousDraw) {
            this->setIndexSourceToBuffer(fQuadIndexBuffer);
            this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
            fCurrQuad = 1;
            fLastRectVertexLayout = layout;
        }
        if (disabledClip) {
            drawState->enableState(GrDrawState::kClip_StateBit);
        }
        fInstancedDrawTracker.reset();
    } else {
        INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
    }
}
Example #11
0
void
star(void)
{
	double xm, ym, zm, dxm, dym, dzm;
	double xx, yx, zx, yy, zy, zz, tau;
	double capt0, capt1, capt12, capt13, sl, sb, cl;

/*
 *	remove E-terms of aberration
 *	except when finding catalog mean places
 */

	alpha += (.341/(3600.*15.))*sin((alpha+11.26)*15.*radian)
		  /cos(delta*radian);
	delta += (.341/3600.)*cos((alpha+11.26)*15.*radian)
		  *sin(delta*radian) - (.029/3600.)*cos(delta*radian);

/*
 *	correct for proper motion
 */

	tau = (eday - epoch)/365.24220;
	alpha += tau*da/3600.;
	delta += tau*dd/3600.;
	alpha *= 15.*radian;
	delta *= radian;

/*
 *	convert to rectangular coordinates merely for convenience
 */

	xm = cos(delta)*cos(alpha);
	ym = cos(delta)*sin(alpha);
	zm = sin(delta);

/*
 *	convert mean places at epoch of startable to current
 *	epoch (i.e. compute relevant precession)
 */

	capt0 = (epoch - 18262.427)/36524.220e0;
	capt1 = (eday - epoch)/36524.220;
	capt12 = capt1*capt1;
	capt13 = capt12*capt1;

	xx = - (.00029696+26.e-8*capt0)*capt12
		  - 13.e-8*capt13;
	yx =  -(.02234941+1355.e-8*capt0)*capt1
		  - 676.e-8*capt12 + 221.e-8*capt13;
	zx = -(.00971690-414.e-8*capt0)*capt1
		  + 207.e-8*capt12 + 96.e-8*capt13;
	yy = - (.00024975+30.e-8*capt0)*capt12
		  - 15.e-8*capt13;
	zy = -(.00010858+2.e-8*capt0)*capt12;
	zz = - (.00004721-4.e-8*capt0)*capt12;

	dxm =  xx*xm + yx*ym + zx*zm;
	dym = - yx*xm + yy*ym + zy*zm;
	dzm = - zx*xm + zy*ym + zz*zm;

	xm = xm + dxm;
	ym = ym + dym;
	zm = zm + dzm;

/*
 *	convert to mean ecliptic system of date
 */

	alpha = atan2(ym, xm);
	delta = atan2(zm, sqrt(xm*xm+ym*ym));
	cl = cos(delta)*cos(alpha);
	sl = cos(delta)*sin(alpha)*cos(obliq) + sin(delta)*sin(obliq);
	sb = -cos(delta)*sin(alpha)*sin(obliq) + sin(delta)*cos(obliq);
	lambda = atan2(sl, cl);
	beta = atan2(sb, sqrt(cl*cl+sl*sl));
	rad = 1.e9;
	if(px != 0)
		rad = 20600/px;
	motion = 0;
	semi = 0;

	helio();
	geo();
}
Example #12
0
void
jup(void)
{
	double pturbl, pturbb, pturbr;
	double lograd;
	double dele, enom, vnom, nd, sl;


	ecc = .0483376 + 163.e-6*capt;
	incl = 1.308660 - .0055*capt;
	node = 99.43785 + 1.011*capt;
	argp = 12.71165 + 1.611*capt;
	mrad = 5.202803;
	anom = 225.22165 + .0830912*eday - .0484*capt;
	motion = 299.1284/3600.;

	incl *= radian;
	node *= radian;
	argp *= radian;
	anom = fmod(anom,360.)*radian;

	enom = anom + ecc*sin(anom);
	do {
		dele = (anom - enom + ecc * sin(enom)) /
			(1. - ecc*cos(enom));
		enom += dele;
	} while(fabs(dele) > converge);
	vnom = 2.*atan2(sqrt((1.+ecc)/(1.-ecc))*sin(enom/2.),
		cos(enom/2.));
	rad = mrad*(1. - ecc*cos(enom));

	lambda = vnom + argp;

	pturbl = 0.;

	lambda += pturbl*radsec;

	pturbb = 0.;

	pturbr = 0.;

/*
 *	reduce to the ecliptic
 */

	nd = lambda - node;
	lambda = node + atan2(sin(nd)*cos(incl),cos(nd));

	sl = sin(incl)*sin(nd) + pturbb*radsec;
	beta = atan2(sl, pyth(sl));

	lograd = pturbr*2.30258509;
	rad *= 1. + lograd;


	lambda += 555.*radsec;
	beta -= 51.*radsec;
	motion *= radian*mrad*mrad/(rad*rad);
	semi = 98.47;

	mag = -8.93;
	helio();
	geo();
}
Example #13
0
UpcomingEventsWidget::UpcomingEventsWidget( const LastFmEventPtr &event,
                                            QGraphicsItem *parent,
                                            Qt::WindowFlags wFlags )
    : QGraphicsWidget( parent, wFlags )
    , m_mapButton( 0 )
    , m_urlButton( 0 )
    , m_image( new QLabel )
    , m_event( event )
{
    setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );

    m_image->setText( i18n("Loading picture...") );
    m_image->setAttribute( Qt::WA_NoSystemBackground );
    m_image->setAlignment( Qt::AlignCenter );
    m_image->setFixedSize( 128, 128 );
    QGraphicsProxyWidget *imageProxy = new QGraphicsProxyWidget( this );
    imageProxy->setWidget( m_image );

    m_attendance   = createLabel();
    m_date         = createLabel();
    m_location     = createLabel();
    m_name         = createLabel();
    m_participants = createLabel();
    m_tags         = createLabel();
    m_venue        = createLabel();

    QGraphicsLinearLayout *buttonsLayout = new QGraphicsLinearLayout( Qt::Horizontal );
    buttonsLayout->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Fixed );
    if( event && event->venue() && event->venue()->location )
    {
        QPointF geo( event->venue()->location->longitude, event->venue()->location->latitude );
        if( !geo.isNull() )
        {
            m_mapButton = new Plasma::PushButton( this );
            m_mapButton->setMaximumSize( QSizeF( 22, 22 ) );
            m_mapButton->setIcon( KIcon("edit-find") ); // TODO: a map icon would be nice
            m_mapButton->setToolTip( i18n( "View map" ) );
            buttonsLayout->addItem( m_mapButton );
        }
    }

    if( event && event->url().isValid() )
    {
        m_urlButton = new Plasma::PushButton( this );
        m_urlButton->setMaximumSize( QSizeF( 22, 22 ) );
        m_urlButton->setIcon( KIcon("applications-internet") );
        m_urlButton->setToolTip( i18n( "Open Last.fm webpage for this event" ) );
        connect( m_urlButton, SIGNAL(clicked()), this, SLOT(openUrl()) );
        buttonsLayout->addItem( m_urlButton );
    }

    QSizePolicy::Policy minPol = QSizePolicy::Minimum;
    QGraphicsWidget *supportLabel, *venueLabel, *locationLabel, *dateLabel, *attendLabel, *tagsLabel;
    supportLabel  = createLabel( i18nc("@label:textbox Supporing acts for an event", "Supporting:"), minPol );
    venueLabel    = createLabel( i18nc("@label:textbox", "Venue:"), minPol );
    locationLabel = createLabel( i18nc("@label:textbox", "Location:"), minPol );
    dateLabel     = createLabel( i18nc("@label:textbox", "Date:"), minPol );
    attendLabel   = createLabel( i18nc("@label:textbox", "Attending:"), minPol );
    tagsLabel     = createLabel( i18nc("@label:textbox", "Tags:"), minPol );

    QGraphicsGridLayout *infoLayout = new QGraphicsGridLayout;
    infoLayout->addItem( supportLabel, 0, 0 );
    infoLayout->addItem( venueLabel, 1, 0 );
    infoLayout->addItem( locationLabel, 2, 0 );
    infoLayout->addItem( dateLabel, 3, 0 );
    infoLayout->addItem( attendLabel, 4, 0 );
    infoLayout->addItem( tagsLabel, 5, 0 );
    infoLayout->addItem( m_participants, 0, 1 );
    infoLayout->addItem( m_venue, 1, 1 );
    infoLayout->addItem( m_location, 2, 1 );
    infoLayout->addItem( m_date, 3, 1 );
    infoLayout->addItem( m_attendance, 4, 1 );
    infoLayout->addItem( m_tags, 5, 1 );

    QGraphicsGridLayout *layout = new QGraphicsGridLayout;
    layout->addItem( imageProxy, 0, 0, 2, 1, Qt::AlignCenter );
    layout->addItem( m_name, 0, 1 );
    layout->addItem( buttonsLayout, 0, 2, Qt::AlignRight );
    layout->addItem( infoLayout, 1, 1, 1, 2 );
    setLayout( layout );

    QString name = event->name();
    if( event->isCancelled() )
        name = i18nc( "@label:textbox Title for a canceled upcoming event", "<s>%1</s> (Canceled)", name );
    setName( name );
    setDate( event->date() );
    setLocation( event->venue()->location );
    setVenue( event->venue() );
    setAttendance( event->attendance() );
    setParticipants( event->participants() );
    setTags( event->tags() );
    setImage( event->imageUrl(LastFmEvent::Large) );
}
Example #14
0
int main(int argc, char* argv[])
{
	if (argc < 5)
	{
		std::cout << "program " << argv[0] << " takes a *layered* mesh file and closed polylines from a geometry and "
		                                      "computes the surface mesh nodes within the closed polyline"
		          << std::endl;
		std::cout << "Usage: " << std::endl
		          << argv[0] << "\n\t--mesh ogs_meshfile\n\t--geometry ogs_geometry_as_gli_file" << std::endl;
		return -1;
	}

	// *** read mesh
	std::string tmp(argv[1]);
	if (tmp.find("--mesh") == std::string::npos)
	{
		std::cout << "could not extract mesh file name" << std::endl;
		return -1;
	}

	tmp = argv[2];
	std::string file_base_name(tmp);
	if (tmp.find(".msh") != std::string::npos)
		file_base_name = tmp.substr(0, tmp.size() - 4);

	std::vector<MeshLib::CFEMesh*> mesh_vec;
	FEMRead(file_base_name, mesh_vec);
	if (mesh_vec.empty())
	{
		std::cerr << "could not read mesh from file " << std::endl;
		return -1;
	}
	MeshLib::CFEMesh* mesh(mesh_vec[mesh_vec.size() - 1]);
	mesh->ConstructGrid();

	// extract path
	std::string path;
	BaseLib::extractPath(argv[2], path);

	// *** read geometry
	tmp = argv[3];
	if (tmp.find("--geometry") == std::string::npos)
	{
		std::cout << "could not extract geometry file name" << std::endl;
		return -1;
	}

	GEOLIB::GEOObjects* geo(new GEOLIB::GEOObjects);
	tmp = argv[4];
	std::string unique_name;
	std::vector<std::string> error_strings;
	FileIO::readGLIFileV4(tmp, geo, unique_name, error_strings);

	//	{
	//		const std::vector<GEOLIB::Point*>* pnts (geo->getPointVec (tmp));
	//		if (pnts) {
	//			std::string fname ("MeshIDs.txt");
	//			std::ofstream out (fname.c_str());
	//
	//			std::string fname_gli ("MeshNodesAsPnts.gli");
	//			std::ofstream pnt_out (fname_gli.c_str());
	//			pnt_out << "#POINTS" << std::endl;
	//
	//			MeshLib::ExtractMeshNodes extract_mesh_nodes (mesh);
	//
	//			const size_t n_pnts (pnts->size());
	//			for (size_t k(0); k<n_pnts; k++) {
	//				extract_mesh_nodes.writeNearestMeshNodeToPoint (out, pnt_out, *((*pnts)[k]));
	//			}
	//			pnt_out << "#STOP" << std::endl;
	//		}
	//		return 0;
	//	}

	// *** get Polygon
	const std::vector<GEOLIB::Polyline*>* plys(geo->getPolylineVec(unique_name));
	if (!plys)
	{
		std::cout << "could not get vector of polylines" << std::endl;
		delete mesh;
		delete geo;
		return -1;
	}

	std::vector<size_t> mesh_ids;
	//	size_t ply_id (0);
	//	size_t layer(1);
	//	getMeshNodesFromLayerAlongPolyline(mesh, geo, unique_name, ply_id, layer, mesh_ids);
	//	writeMeshNodes(mesh, mesh_ids, "MeshIDs.txt", "MeshNodesAsPoints.gli", true);

	//*** extract surface out of mesh
	MeshLib::ExtractMeshNodes extract_mesh_nodes(mesh);

	//	// *** generate a polygon from polyline
	////	std::vector<GEOLIB::Polyline*> polylines;
	//	const size_t n_plys (plys->size());
	//	for (size_t k(0); k < n_plys; k++)
	//	{
	//		bool closed ((*plys)[k]->isClosed());
	//		if (!closed)
	//		{
	//			std::cout << "converting polyline " << k << " to closed polyline" << std::endl;
	//			GEOLIB::Polygon* polygon(NULL);
	//			extract_mesh_nodes.getPolygonFromPolyline(*((*plys)[k]), geo, unique_name, polygon);
	////			polylines.push_back (polygon);
	////			geo->appendPolylineVec (polylines, unique_name);
	//			std::string *polygon_name(new std::string);
	//			geo->getPolylineVecObj(unique_name)->getNameOfElementByID(k, *polygon_name);
	//			(*polygon_name) += "-Polygon";
	//			geo->getPolylineVecObj(unique_name)->push_back(polygon, polygon_name);
	////			polylines.clear();
	//		}
	//	}
	//
	//	FileIO::writeGLIFileV4 ("New.gli", unique_name, *geo);

	// *** search mesh nodes for direct assigning bc, st or ic
	const size_t n_plys(plys->size());
	for (size_t k(0); k < n_plys; k++)
	{
		bool closed((*plys)[k]->isClosed());
		if (!closed)
		{
			std::cout << "polyline " << k << " is not closed" << std::endl;
		}
		else
		{
			std::string fname(path + "MeshIDs.txt");
			std::ofstream out(fname.c_str());
			std::string fname_gli(path + "MeshNodesAsPnts.gli");
			std::ofstream pnt_out(fname_gli.c_str());
			pnt_out << "#POINTS" << std::endl;
			GEOLIB::Polygon polygon(*((*plys)[k]));
			//			extract_mesh_nodes.writeMesh2DNodeIDAndArea (out, pnt_out, polygon);
			extract_mesh_nodes.writeTopSurfaceMeshNodeIDs(out, pnt_out, polygon);
			// write all nodes - not only the surface nodes
			//			extract_mesh_nodes.writeMeshNodeIDs (out, pnt_out, polygon);
			pnt_out << "#STOP" << std::endl;
			out.close();
			pnt_out.close();
		}
	}

	// *** for Model Pipiripau
	//	std::vector<GEOLIB::Polygon*> holes;
	//	size_t bounding_polygon_id(0);
	//	while (bounding_polygon_id < n_plys && ! (*plys)[bounding_polygon_id]->isClosed()) {
	//		bounding_polygon_id++;
	//	}
	//
	//	for (size_t k(bounding_polygon_id+1); k<n_plys; k++) {
	//		bool closed ((*plys)[k]->isClosed());
	//		if (!closed) {
	//			std::cout << "polyline " << k << " is not closed" << std::endl;
	//		} else {
	//			holes.push_back (new GEOLIB::Polygon(*(((*plys)[k]))));
	//		}
	//	}
	//	extract_mesh_nodes.writeMesh2DNodeIDAndArea (out, pnt_out, GEOLIB::Polygon((*((*plys)[bounding_polygon_id]))),
	// holes);
	//	for (size_t k(0); k<holes.size(); k++) {
	//		delete holes[k];
	//	}

	//	out << "#STOP" << std::endl;
	//	out.close();
	//
	//	pnt_out << "#STOP" << std::endl;
	//	pnt_out.close ();

	delete mesh;
	delete geo;

	return 0;
}
Example #15
0
void
plut(void)
{
	double pturbl, pturbb, pturbr;
	double lograd;
	double dele, enom, vnom, nd, sl;

	double capj, capn, eye, comg, omg;
	double sb, su, cu, u, b, up;
	double sd, ca, sa;

	double cy;

	cy = (eday - elem[0]) / 36525.;		/* per julian century */

	mrad = elem[1] + elem[1+6]*cy;
	ecc = elem[2] + elem[2+6]*cy;

	cy = cy / 3600;				/* arcsec/deg per julian century */
	incl = elem[3] + elem[3+6]*cy;
	node = elem[4] + elem[4+6]*cy;
	argp = elem[5] + elem[5+6]*cy;

	anom = elem[6] + elem[6+6]*cy - argp;
	motion = elem[6+6] / 36525. / 3600;

	incl *= radian;
	node *= radian;
	argp *= radian;
	anom = fmod(anom,360.)*radian;

	enom = anom + ecc*sin(anom);
	do {
		dele = (anom - enom + ecc * sin(enom)) /
			(1. - ecc*cos(enom));
		enom += dele;
	} while(fabs(dele) > converge);
	vnom = 2.*atan2(sqrt((1.+ecc)/(1.-ecc))*sin(enom/2.),
		cos(enom/2.));
	rad = mrad*(1. - ecc*cos(enom));

	lambda = vnom + argp;
	pturbl = 0.;
	lambda += pturbl*radsec;
	pturbb = 0.;
	pturbr = 0.;

/*
 *	reduce to the ecliptic
 */

	nd = lambda - node;
	lambda = node + atan2(sin(nd)*cos(incl),cos(nd));

	sl = sin(incl)*sin(nd) + pturbb*radsec;
	beta = atan2(sl, pyth(sl));

	lograd = pturbr*2.30258509;
	rad *= 1. + lograd;


	lambda -= 1185.*radsec;
	beta -= 51.*radsec;

	motion *= radian*mrad*mrad/(rad*rad);
	semi = 83.33;

/*
 *	here begins the computation of magnitude
 *	first find the geocentric equatorial coordinates of Saturn
 */

	sd = rad*(cos(beta)*sin(lambda)*sin(obliq) +
		sin(beta)*cos(obliq));
	sa = rad*(cos(beta)*sin(lambda)*cos(obliq) -
		sin(beta)*sin(obliq));
	ca = rad*cos(beta)*cos(lambda);
	sd += zms;
	sa += yms;
	ca += xms;
	alpha = atan2(sa,ca);
	delta = atan2(sd,sqrt(sa*sa+ca*ca));

/*
 *	here are the necessary elements of Saturn's rings
 *	cf. Exp. Supp. p. 363ff.
 */

	capj = 6.9056 - 0.4322*capt;
	capn = 126.3615 + 3.9894*capt + 0.2403*capt2;
	eye = 28.0743 - 0.0128*capt;
	comg = 168.1179 + 1.3936*capt;
	omg = 42.9236 - 2.7390*capt - 0.2344*capt2;

	capj *= radian;
	capn *= radian;
	eye *= radian;
	comg *= radian;
	omg *= radian;

/*
 *	now find saturnicentric ring-plane coords of the earth
 */

	sb = sin(capj)*cos(delta)*sin(alpha-capn) -
		cos(capj)*sin(delta);
	su = cos(capj)*cos(delta)*sin(alpha-capn) +
		sin(capj)*sin(delta);
	cu = cos(delta)*cos(alpha-capn);
	u = atan2(su,cu);
	b = atan2(sb,sqrt(su*su+cu*cu));

/*
 *	and then the saturnicentric ring-plane coords of the sun
 */

	su = sin(eye)*sin(beta) +
		cos(eye)*cos(beta)*sin(lambda-comg);
	cu = cos(beta)*cos(lambda-comg);
	up = atan2(su,cu);

/*
 *	at last, the magnitude
 */


	sb = sin(b);
	mag = -8.68 +2.52*fabs(up+omg-u)-
		2.60*fabs(sb) + 1.25*(sb*sb);

	helio();
	geo();
}
Example #16
0
Graph *
geo_hier(long seed,
	int nlevels,	/* number of levels (=size of following array) */
	int edgemeth,	/* method of attaching edges */
	int aux,	/* auxiliary parameter for edge method (threshold) */
	geo_parms *pp)	/* array of parameter structures, one per level */
{
Graph *newG, *tG, *GG, *srcG, *dstG;
long *numv;		/* array of sizes of lower-level graphs */
geo_parms *curparms, workparms[MAXLEVEL];
register i,k,indx;
long dst;
int temp,total,lowsize,otherend,blen,level;
long maxP[MAXLEVEL], maxDiam[MAXLEVEL], wt[MAXLEVEL];
Vertex *np,*vp,*up,*base;
Arc *ap;
char vnamestr[MAXNAMELEN];


     if (seed)		/* convention: zero seed means don't use */
	gb_init_rand(seed);

     if (nlevels < 1 || nlevels > MAXLEVEL) {
	gb_trouble_code = bad_specs+HIER_TRBL;
	return NULL;
     }

     /* 1 <= nlevels <= MAXLEVEL */

     /* copy the parameters so we can modify them, and caller doesn't
      * see the changes.
      */
     for (level=0; level<nlevels; level++)
	bcopy((char *)&pp[level],&workparms[level],sizeof(geo_parms));

     level = 0;

     gb_trouble_code = 0;
     
     tG = NULL;
     do {
	gb_recycle(tG);
        tG = geo(0L,workparms);
     } while (tG != NULL && !isconnected(tG));

     if (tG==NULL)
	return tG;

     maxDiam[0] = fdiam(tG);
     maxP[0] = maxDiam[0];
     wt[0] = 1;

     for (i=1; i<nlevels; i++)
       maxDiam[i] = -1;

     curparms = workparms;

     while (++level < nlevels) {
       long tdiam;

	curparms++;	/* parameters for graphs @ next level */

        /* spread out the numbers of nodes per graph at this level */
	numv = (long *) calloc(tG->n,sizeof(long));
	lowsize = curparms->n;
        randomize(numv,tG->n,curparms->n,3*tG->n);

	/* create a subordinate graph for each vertex in the "top" graph,
         * and add it into the new graph as a whole.
	 * We construct the subgraphs all at once to ensure that each
	 * has a unique address.
	 */
	for (i=0,vp=tG->vertices; i<tG->n; i++,vp++) {
	    curparms->n = numv[i];
	    do {
		newG = geo(0L,curparms);
		if (newG==NULL) return NULL;
	    } while (!isconnected(newG));
	    vp->sub = newG;
	    tdiam = fdiam(newG);
	    if (tdiam>maxDiam[level])
	      maxDiam[level] = tdiam;
	}

	/* do some calculations before "flattening" the top Graph */

	total = 0;

	for (i=0; i<tG->n; i++) {	/* translate node numbers */
	    temp = numv[i];		
	    numv[i]= total;
	    total += temp;
	}

	if (total != tG->n*lowsize) {
	    fprintf(stderr,"bad size of new graph!\n");
	    fprintf(stderr,"total %d tG->n %ld lowsize %d\n",total,tG->n,lowsize);
	    gb_trouble_code = impossible+HIER_TRBL;
	    return NULL;
	}

	/* now create what will become the "new" top-level graph */
	newG = gb_new_graph(total);
	if (newG==NULL) {
	    gb_trouble_code += HIER_TRBL;
	    return NULL;
	}

	/* resolution of the new graph */
	newG->Gscale = tG->Gscale * curparms->scale;

       /* compute edge weights for this level */

       wt[level] = maxP[level-1] + 1;
       maxP[level] = (maxDiam[level]*wt[level])
	 + (maxDiam[level-1]*maxP[level-1]);

       for (i=0,vp=tG->vertices; i<tG->n; i++,vp++) {
	 strcpy(vnamestr,vp->name);	/* base name for all "offspring" */
	 blen = strlen(vnamestr);
	 vnamestr[blen] = '.';
	    
	 GG = tG->vertices[i].sub;
	 base = newG->vertices + numv[i];	/* start of this node's */
	 for (k=0,np=base,up=GG->vertices; k<GG->n; k++,np++,up++) {

	   /* add the node's edges */
	   for (ap=up->arcs; ap; ap=ap->next)  {
	     otherend = ap->tip - GG->vertices;
	     if (k < otherend)
	       gb_new_edge(np,base+otherend,ap->len);
	     
	   }

	   /* now set the new node's position */
	   np->xpos = tG->vertices[i].xpos * curparms->scale + up->xpos;
	   np->ypos = tG->vertices[i].ypos * curparms->scale + up->ypos;

	   /* give the "new" node a name by catenating top & bot names */
	   strcpy(vnamestr+blen+1,up->name);
	   np->name = gb_save_string(vnamestr);

	 } /* loop over GG's vertices */
       }  /* loop over top-level vertices */

       /*
	* Now we have to transfer the top-level edges to new graph.
	* This is done by one of three methods:
	*    0: choose a random node in each subgraph
	*    1: attach to the smallest-degree non-leaf node in each
	*    2: attach to smallest-degree node
	*    3: attach to first node with degree less than aux
	*/
       for (i=0; i<tG->n; i++) {
	 Vertex *srcp, *dstp;
	 Graph *srcG, *dstG;

	 srcG = tG->vertices[i].sub;

	 if (srcG == NULL) {	/* paranoia */
	   gb_trouble_code = impossible+HIER_TRBL+1;
	   return NULL;
	 }

	 for (ap=tG->vertices[i].arcs; ap; ap=ap->next) {

	   dst = ap->tip - tG->vertices;

	   if (i > dst)	/* consider each edge only ONCE */
	     continue;

	   dstG = ap->tip->sub;

	   if (dstG == NULL) {	/* paranoia */
	     gb_trouble_code = impossible+HIER_TRBL+1;
	     return NULL;
	   }

	   /* choose endpoints of the top-level edge */

	   switch (edgemeth) {
	   case 0:	/* choose random node in each */
	     srcp = srcG->vertices + gb_next_rand()%srcG->n;
	     dstp = dstG->vertices + gb_next_rand()%dstG->n;
	     break;

	   case 1:	/* find nonleaf node of least degree in each */
	     /* This causes problems with graph size < 3 */
	     if (srcG->n > 2)
	       srcp = find_small_deg(srcG,NOLEAF);
	     else
	       srcp = find_small_deg(srcG,LEAFOK);
	     if (dstG->n > 2)
	       dstp = find_small_deg(dstG,NOLEAF);
	     else
	       dstp = find_small_deg(dstG,LEAFOK);
	     break;

	   case 2: /* find node of smallest degree */
	     srcp = find_small_deg(srcG,LEAFOK);
	     dstp = find_small_deg(dstG,LEAFOK);
	     break;

	   case 3: /* first node w/degree < aux */
	     srcp = find_thresh_deg(srcG,aux);
	     dstp = find_thresh_deg(dstG,aux);
	   default:
	     gb_trouble_code = bad_specs+HIER_TRBL;
	     return NULL;

	   }	/* switch on edgemeth */

	   /* pointer arithmetic: isn't it fun?
	      printf("Copying edge from %d to %d\n",
	      numv[i]+(srcp - srcG->vertices),
	      numv[dst] + (dstp - dstG->vertices));
	      */
	   if (srcp==NULL || dstp==NULL) {
	     gb_trouble_code = impossible + HIER_TRBL+2;
	     return NULL;
	   }
		
	   srcp = newG->vertices + numv[i] + (srcp - srcG->vertices);
	   dstp = newG->vertices + numv[dst] + (dstp - dstG->vertices);

	   gb_new_edge(srcp,dstp,idist(srcp,dstp));

	 } /* for each arc */
       } /* for each vertex of top graph */

        /* now make the "new" graph the "top" graph and recycle others */
       for (i=0,vp=tG->vertices; i<tG->n; i++,vp++)
	 gb_recycle(vp->sub);

       gb_recycle(tG);

       tG = newG;

       free(numv);
     }	/* while more levels */

/* Finally, go back and add the policy weights,
 * based upon the computed max diameters
 * and Max Path lengths.
 */
   for (i=0; i<tG->n; i++)
     for (ap=tG->vertices[i].arcs; ap; ap=ap->next) {
       dst = ap->tip - tG->vertices;
       if (i > dst)	/* consider each edge only ONCE */
	 continue;

       assert(i != dst); /* no self loops */

       /* i < dst: it is safe to refer to ap's mate by ap+1.  */
       level = edge_level(&tG->vertices[i],&tG->vertices[dst],nlevels);
       ap->policywt = (ap+1)->policywt = wt[level];

     }

/* construct the utility and id strings for the new graph.
 * Space constraints will restrict us to keeping about 4 levels'
 * worth of info.
 */
  {
    char buf[ID_FIELD_SIZE+1];
    register char *cp;
    int len, nextlen, left;

    strcpy(tG->util_types,GEO_UTIL);	/* same for all geo graphs,	*/
					/* defined in geo.h		*/
    cp = tG->id;
    sprintf(cp,"geo_hier(%ld,%d,%d,%d,[",seed,nlevels,edgemeth,aux);
    len = strlen(cp);
    left = ID_FIELD_SIZE - len;
    cp += len;
    
    for (i=0; (i < nlevels) && (left > 0); i++) {
      nextlen = printparms(buf,&pp[i]);
      strncpy(cp,buf,left);
      left -= nextlen;
      cp += nextlen;
    }
    if (left > 0) {
      sprintf(buf,"])");
      nextlen = strlen(buf);
      strncpy(cp,buf,left);
    }
  }

  return tG;
}	/* geo_hier() */
Example #17
0
void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
                                   const GrMatrix* matrix,
                                   StageMask stageMask,
                                   const GrRect* srcRects[],
                                   const GrMatrix* srcMatrices[]) {

    GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
    GrAssert(!(fDraws.empty() && fCurrQuad));
    GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));

    GrDrawState* drawState = this->drawState();

    // if we have a quad IB then either append to the previous run of
    // rects or start a new run
    if (fMaxQuads) {

        bool appendToPreviousDraw = false;
        GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
        AutoReleaseGeometry geo(this, layout, 4, 0);
        if (!geo.succeeded()) {
            GrPrintf("Failed to get space for vertices!\n");
            return;
        }
        GrMatrix combinedMatrix = drawState->getViewMatrix();
        // We go to device space so that matrix changes allow us to concat
        // rect draws. When the caller has provided explicit source rects
        // then we don't want to modify the sampler matrices. Otherwise we do
        // we have to account for the view matrix change in the sampler
        // matrices.
        StageMask devCoordMask = (NULL == srcRects) ? stageMask : 0;
        GrDrawTarget::AutoDeviceCoordDraw adcd(this, devCoordMask);
        if (NULL != matrix) {
            combinedMatrix.preConcat(*matrix);
        }

        SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());

        // we don't want to miss an opportunity to batch rects together
        // simply because the clip has changed if the clip doesn't affect
        // the rect.
        bool disabledClip = false;
        if (drawState->isClipState() && fClip.isRect()) {

            GrRect clipRect = fClip.getRect(0);
            // If the clip rect touches the edge of the viewport, extended it
            // out (close) to infinity to avoid bogus intersections.
            // We might consider a more exact clip to viewport if this
            // conservative test fails.
            const GrRenderTarget* target = drawState->getRenderTarget();
            if (0 >= clipRect.fLeft) {
                clipRect.fLeft = GR_ScalarMin;
            }
            if (target->width() <= clipRect.fRight) {
                clipRect.fRight = GR_ScalarMax;
            }
            if (0 >= clipRect.top()) {
                clipRect.fTop = GR_ScalarMin;
            }
            if (target->height() <= clipRect.fBottom) {
                clipRect.fBottom = GR_ScalarMax;
            }
            int stride = VertexSize(layout);
            bool insideClip = true;
            for (int v = 0; v < 4; ++v) {
                const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
                if (!clipRect.contains(p)) {
                    insideClip = false;
                    break;
                }
            }
            if (insideClip) {
                drawState->disableState(GrDrawState::kClip_StateBit);
                disabledClip = true;
            }
        }
        if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
            fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {

            int vsize = VertexSize(layout);

            Draw& lastDraw = fDraws.back();

            GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
            GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
            GrAssert(0 == lastDraw.fVertexCount % 4);
            GrAssert(0 == lastDraw.fIndexCount % 6);
            GrAssert(0 == lastDraw.fStartIndex);

            GeometryPoolState& poolState = fGeoPoolStateStack.back();
            bool clearSinceLastDraw =
                            fClears.count() && 
                            fClears.back().fBeforeDrawIdx == fDraws.count();

            appendToPreviousDraw =  
                !clearSinceLastDraw &&
                lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
                (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;

            if (appendToPreviousDraw) {
                lastDraw.fVertexCount += 4;
                lastDraw.fIndexCount += 6;
                fCurrQuad += 1;
                // we reserved above, so we should be the first
                // use of this vertex reserveation.
                GrAssert(0 == poolState.fUsedPoolVertexBytes);
                poolState.fUsedPoolVertexBytes = 4 * vsize;
            }
        }
        if (!appendToPreviousDraw) {
            this->setIndexSourceToBuffer(fQuadIndexBuffer);
            this->drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
            fCurrQuad = 1;
            fLastRectVertexLayout = layout;
        }
        if (disabledClip) {
            drawState->enableState(GrDrawState::kClip_StateBit);
        }
        fInstancedDrawTracker.reset();
    } else {
        INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
    }
}
Example #18
0
void TransitionCanvas::menu(const QPoint &) {
  if ((data != 0) && !data->get_start()->in_edition()) {
    TransitionCanvas * plabel;
    TransitionCanvas * pstereotype;
    
    {
      ArrowCanvas * aplabel;
      ArrowCanvas * apstereotype;
      
      search_supports(aplabel, apstereotype);
      plabel = (TransitionCanvas *) aplabel;
      pstereotype = (TransitionCanvas *) apstereotype;
    }
    
    QPopupMenu m(0);
    QPopupMenu geo(0);
    QPopupMenu toolm(0);
    
    m.insertItem(new MenuTitle(data->definition(FALSE, TRUE), m.font()),
		 -1);
    m.insertSeparator();
    m.insertItem("Edit", 0);
    m.insertSeparator();

    m.insertItem("Select in browser", 2);
    if (plabel || pstereotype) {
      m.insertSeparator();
      m.insertItem("Edit drawing settings", 1);
      m.insertItem("Select labels", 3);
      m.insertItem("Labels default position", 4);
      if (plabel && (label == 0))
	m.insertItem("Attach transition's name to this segment", 5);
      if (pstereotype && (stereotype == 0))
	m.insertItem("Attach stereotype to this segment", 6);
    }
  
    if (get_start() != get_end()) {
      m.insertSeparator();
      init_geometry_menu(geo, 10);
      m.insertItem("Geometry (Ctrl+l)", &geo);
    }
    
    m.insertSeparator();
    m.insertItem("Remove from diagram",7);
    if (data->get_start()->is_writable())
      m.insertItem("Delete from model", 8);
    
    m.insertSeparator();
    if (Tool::menu_insert(&toolm, itstype, 20))
      m.insertItem("Tool", &toolm);
    
    int rank = m.exec(QCursor::pos());
    
    switch (rank) {
    case 0:
      data->edit();
      return;
    case 1:
      edit_drawing_settings();
      return;
    case 2:
      data->get_start()->select_in_browser();
      return;
    case 3:
      the_canvas()->unselect_all();
      if (plabel)
	the_canvas()->select(plabel->label);
      if (pstereotype)
	the_canvas()->select(pstereotype->stereotype);
      return;
    case 4:
      if (plabel)
	plabel->default_label_position();
      if (pstereotype)
	pstereotype->stereotype_default_position();
      return;
    case 5:
      label = plabel->label;
      plabel->label = 0;
      default_label_position();
      return;
    case 6:
      stereotype = pstereotype->stereotype;
      pstereotype->stereotype = 0;
      if (label != 0)
	default_label_position();
      stereotype_default_position();
      return;
    case 7:
      // not removed from the browser : just hide it
      remove(FALSE);
      break;
    case 8:
      data->delete_it();	// will delete the canvas
      break;
    default:
      if (rank >= 20) {
	ToolCom::run(Tool::command(rank - 20), data->get_start());
	return;
      }
      else if (rank >= 10) {
	rank -= 10;
	if (rank == RecenterBegin)
	  set_decenter(-1.0, decenter_end);
	else if (rank == RecenterEnd)
	  set_decenter(decenter_begin, -1.0);
	else if (rank != (int) geometry)
	  set_geometry((LineGeometry) rank, TRUE);
	else
	  return;
      }
      else
	return;
    }
    
    package_modified();
  }
}
Example #19
0
bool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const GrPaint& paint,
                                   const GrStrokeInfo& strokeInfo, GrGpu* gpu,
                                   GrDrawTarget* target, const SkMatrix& vm) {

    if (!can_fast_path_dash(pts, strokeInfo, *target, vm)) {
        return false;
    }

    const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo();

    SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap();

    SkScalar srcStrokeWidth = strokeInfo.getStrokeRec().getWidth();

    // the phase should be normalized to be [0, sum of all intervals)
    SkASSERT(info.fPhase >= 0 && info.fPhase < info.fIntervals[0] + info.fIntervals[1]);

    SkScalar srcPhase = info.fPhase;

    // Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[1].fX
    SkMatrix srcRotInv;
    SkPoint ptsRot[2];
    if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) {
        SkMatrix rotMatrix;
        align_to_x_axis(pts, &rotMatrix, ptsRot);
        if(!rotMatrix.invert(&srcRotInv)) {
            GrPrintf("Failed to create invertible rotation matrix!\n");
            return false;
        }
    } else {
        srcRotInv.reset();
        memcpy(ptsRot, pts, 2 * sizeof(SkPoint));
    }

    bool useAA = paint.isAntiAlias();

    // Scale corrections of intervals and stroke from view matrix
    SkScalar parallelScale;
    SkScalar perpScale;
    calc_dash_scaling(&parallelScale, &perpScale, vm, ptsRot);

    bool hasCap = SkPaint::kButt_Cap != cap && 0 != srcStrokeWidth;

    // We always want to at least stroke out half a pixel on each side in device space
    // so 0.5f / perpScale gives us this min in src space
    SkScalar halfSrcStroke = SkMaxScalar(srcStrokeWidth * 0.5f, 0.5f / perpScale);

    SkScalar strokeAdj;
    if (!hasCap) {
        strokeAdj = 0.f;
    } else {
        strokeAdj = halfSrcStroke;
    }

    SkScalar startAdj = 0;

    SkMatrix combinedMatrix = srcRotInv;
    combinedMatrix.postConcat(vm);

    bool lineDone = false;
    SkRect startRect;
    bool hasStartRect = false;
    // If we are using AA, check to see if we are drawing a partial dash at the start. If so
    // draw it separately here and adjust our start point accordingly
    if (useAA) {
        if (srcPhase > 0 && srcPhase < info.fIntervals[0]) {
            SkPoint startPts[2];
            startPts[0] = ptsRot[0];
            startPts[1].fY = startPts[0].fY;
            startPts[1].fX = SkMinScalar(startPts[0].fX + info.fIntervals[0] - srcPhase,
                                         ptsRot[1].fX);
            startRect.set(startPts, 2);
            startRect.outset(strokeAdj, halfSrcStroke);

            hasStartRect = true;
            startAdj = info.fIntervals[0] + info.fIntervals[1] - srcPhase;
        }
    }

    // adjustments for start and end of bounding rect so we only draw dash intervals
    // contained in the original line segment.
    startAdj += calc_start_adjustment(info);
    if (startAdj != 0) {
        ptsRot[0].fX += startAdj;
        srcPhase = 0;
    }
    SkScalar endingInterval = 0;
    SkScalar endAdj = calc_end_adjustment(info, ptsRot, srcPhase, &endingInterval);
    ptsRot[1].fX -= endAdj;
    if (ptsRot[0].fX >= ptsRot[1].fX) {
        lineDone = true;
    }

    SkRect endRect;
    bool hasEndRect = false;
    // If we are using AA, check to see if we are drawing a partial dash at then end. If so
    // draw it separately here and adjust our end point accordingly
    if (useAA && !lineDone) {
        // If we adjusted the end then we will not be drawing a partial dash at the end.
        // If we didn't adjust the end point then we just need to make sure the ending
        // dash isn't a full dash
        if (0 == endAdj && endingInterval != info.fIntervals[0]) {
            SkPoint endPts[2];
            endPts[1] = ptsRot[1];
            endPts[0].fY = endPts[1].fY;
            endPts[0].fX = endPts[1].fX - endingInterval;

            endRect.set(endPts, 2);
            endRect.outset(strokeAdj, halfSrcStroke);

            hasEndRect = true;
            endAdj = endingInterval + info.fIntervals[1];

            ptsRot[1].fX -= endAdj;
            if (ptsRot[0].fX >= ptsRot[1].fX) {
                lineDone = true;
            }
        }
    }

    if (startAdj != 0) {
        srcPhase = 0;
    }

    // Change the dashing info from src space into device space
    SkScalar devIntervals[2];
    devIntervals[0] = info.fIntervals[0] * parallelScale;
    devIntervals[1] = info.fIntervals[1] * parallelScale;
    SkScalar devPhase = srcPhase * parallelScale;
    SkScalar strokeWidth = srcStrokeWidth * perpScale;

    if ((strokeWidth < 1.f && !useAA) || 0.f == strokeWidth) {
        strokeWidth = 1.f;
    }

    SkScalar halfDevStroke = strokeWidth * 0.5f;

    if (SkPaint::kSquare_Cap == cap && 0 != srcStrokeWidth) {
        // add cap to on interveal and remove from off interval
        devIntervals[0] += strokeWidth;
        devIntervals[1] -= strokeWidth;
    }
    SkScalar startOffset = devIntervals[1] * 0.5f + devPhase;

    SkScalar bloatX = useAA ? 0.5f / parallelScale : 0.f;
    SkScalar bloatY = useAA ? 0.5f / perpScale : 0.f;

    SkScalar devBloat = useAA ? 0.5f : 0.f;

    GrDrawState* drawState = target->drawState();
    if (devIntervals[1] <= 0.f && useAA) {
        // Case when we end up drawing a solid AA rect
        // Reset the start rect to draw this single solid rect
        // but it requires to upload a new intervals uniform so we can mimic
        // one giant dash
        ptsRot[0].fX -= hasStartRect ? startAdj : 0;
        ptsRot[1].fX += hasEndRect ? endAdj : 0;
        startRect.set(ptsRot, 2);
        startRect.outset(strokeAdj, halfSrcStroke);
        hasStartRect = true;
        hasEndRect = false;
        lineDone = true;

        SkPoint devicePts[2];
        vm.mapPoints(devicePts, ptsRot, 2);
        SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]);
        if (hasCap) {
            lineLength += 2.f * halfDevStroke;
        }
        devIntervals[0] = lineLength;
    }
    if (devIntervals[1] > 0.f || useAA) {
        SkPathEffect::DashInfo devInfo;
        devInfo.fPhase = devPhase;
        devInfo.fCount = 2;
        devInfo.fIntervals = devIntervals;
        GrEffectEdgeType edgeType= useAA ? kFillAA_GrEffectEdgeType :
            kFillBW_GrEffectEdgeType;
        bool isRoundCap = SkPaint::kRound_Cap == cap;
        GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_DashCap :
                                                        GrDashingEffect::kNonRound_DashCap;
        drawState->addCoverageEffect(
            GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType), 1)->unref();
    }

    // Set up the vertex data for the line and start/end dashes
    drawState->setVertexAttribs<gDashLineVertexAttribs>(SK_ARRAY_COUNT(gDashLineVertexAttribs));

    int totalRectCnt = 0;

    totalRectCnt += !lineDone ? 1 : 0;
    totalRectCnt += hasStartRect ? 1 : 0;
    totalRectCnt += hasEndRect ? 1 : 0;

    GrDrawTarget::AutoReleaseGeometry geo(target, totalRectCnt * 4, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return false;
    }

    DashLineVertex* verts = reinterpret_cast<DashLineVertex*>(geo.vertices());

    int curVIdx = 0;

    if (SkPaint::kRound_Cap == cap && 0 != srcStrokeWidth) {
        // need to adjust this for round caps to correctly set the dashPos attrib on vertices
        startOffset -= halfDevStroke;
    }

    // Draw interior part of dashed line
    if (!lineDone) {
        SkPoint devicePts[2];
        vm.mapPoints(devicePts, ptsRot, 2);
        SkScalar lineLength = SkPoint::Distance(devicePts[0], devicePts[1]);
        if (hasCap) {
            lineLength += 2.f * halfDevStroke;
        }

        SkRect bounds;
        bounds.set(ptsRot[0].fX, ptsRot[0].fY, ptsRot[1].fX, ptsRot[1].fY);
        bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke);
        setup_dashed_rect(bounds, verts, curVIdx, combinedMatrix, startOffset, devBloat,
                          lineLength, halfDevStroke);
        curVIdx += 4;
    }

    if (hasStartRect) {
        SkASSERT(useAA);  // so that we know bloatX and bloatY have been set
        startRect.outset(bloatX, bloatY);
        setup_dashed_rect(startRect, verts, curVIdx, combinedMatrix, startOffset, devBloat,
                          devIntervals[0], halfDevStroke);
        curVIdx += 4;
    }

    if (hasEndRect) {
        SkASSERT(useAA);  // so that we know bloatX and bloatY have been set
        endRect.outset(bloatX, bloatY);
        setup_dashed_rect(endRect, verts, curVIdx, combinedMatrix, startOffset, devBloat,
                          devIntervals[0], halfDevStroke);
    }

    target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
    target->drawIndexedInstances(kTriangles_GrPrimitiveType, totalRectCnt, 4, 6);
    target->resetIndexSource();
    return true;
}
Example #20
0
File: moon.c Project: 99years/plan9
void
moon(void)
{
	Moontab *mp;
	double dlong, lsun, psun;
	double eccm, eccs, chp, cpe;
	double v0, t0, m0, j0;
	double arg1, arg2, arg3, arg4, arg5, arg6, arg7;
	double arg8, arg9, arg10;
	double dgamma, k5, k6;
	double lterms, sterms, cterms, nterms, pterms, spterms;
	double gamma1, gamma2, gamma3, arglat;
	double xmp, ymp, zmp;
	double obl2;

/*
 *	the fundamental elements - all referred to the epoch of
 *	Jan 0.5, 1900 and to the mean equinox of date.
 */

	dlong = 270.434164 + 13.1763965268*eday - .001133*capt2
		 + 2.e-6*capt3;
	argp = 334.329556 + .1114040803*eday - .010325*capt2
		 - 12.e-6*capt3;
	node = 259.183275 - .0529539222*eday + .002078*capt2
		 + 2.e-6*capt3;
	lsun = 279.696678 + .9856473354*eday + .000303*capt2;
	psun = 281.220833 + .0000470684*eday + .000453*capt2
		 + 3.e-6*capt3;

	dlong = fmod(dlong, 360.);
	argp = fmod(argp, 360.);
	node = fmod(node, 360.);
	lsun = fmod(lsun, 360.);
	psun = fmod(psun, 360.);

	eccm = 22639.550;
	eccs = .01675104 - .00004180*capt;
	incl = 18461.400;
	cpe = 124.986;
	chp = 3422.451;

/*
 *	some subsidiary elements - they are all longitudes
 *	and they are referred to the epoch 1/0.5 1900 and
 *	to the fixed mean equinox of 1850.0.
 */

	v0 = 342.069128 + 1.6021304820*eday;
	t0 =  98.998753 + 0.9856091138*eday;
	m0 = 293.049675 + 0.5240329445*eday;
	j0 = 237.352319 + 0.0830912295*eday;

/*
 *	the following are periodic corrections to the
 *	fundamental elements and constants.
 *	arg3 is the "Great Venus Inequality".
 */

	arg1 = 41.1 + 20.2*(capt+.5);
	arg2 = dlong - argp + 33. + 3.*t0 - 10.*v0 - 2.6*(capt+.5);
	arg3 = dlong - argp + 151.1 + 16.*t0 - 18.*v0 - (capt+.5);
	arg4 = node;
	arg5 = node + 276.2 - 2.3*(capt+.5);
	arg6 = 313.9 + 13.*t0 - 8.*v0;
	arg7 = dlong - argp + 112.0 + 29.*t0 - 26.*v0;
	arg8 = dlong + argp - 2.*lsun + 273. + 21.*t0 - 20.*v0;
	arg9 = node + 290.1 - 0.9*(capt+.5);
	arg10 = 115. + 38.5*(capt+.5);
	arg1 *= radian;
	arg2 *= radian;
	arg3 *= radian;
	arg4 *= radian;
	arg5 *= radian;
	arg6 *= radian;
	arg7 *= radian;
	arg8 *= radian;
	arg9 *= radian;
	arg10 *= radian;

	dlong +=
		   (0.84 *sin(arg1)
		 +  0.31 *sin(arg2)
		 + 14.27 *sin(arg3)
		 +  7.261*sin(arg4)
		 +  0.282*sin(arg5)
		 +  0.237*sin(arg6)
		 +  0.108*sin(arg7)
		 +  0.126*sin(arg8))/3600.;

	argp +=
		 (- 2.10 *sin(arg1)
		 -  0.118*sin(arg3)
		 -  2.076*sin(arg4)
		 -  0.840*sin(arg5)
		 -  0.593*sin(arg6))/3600.;

	node +=
		   (0.63*sin(arg1)
		 +  0.17*sin(arg3)
		 + 95.96*sin(arg4)
		 + 15.58*sin(arg5)
		 +  1.86*sin(arg9))/3600.;

	t0 +=
		 (- 6.40*sin(arg1)
		 -  1.89*sin(arg6))/3600.;

	psun +=
		   (6.40*sin(arg1)
		 +  1.89*sin(arg6))/3600.;

	dgamma = -  4.318*cos(arg4)
		 -  0.698*cos(arg5)
		 -  0.083*cos(arg9);

	j0 +=
		   0.33*sin(arg10);

/*
 *	the following factors account for the fact that the
 *	eccentricity, solar eccentricity, inclination and
 *	parallax used by Brown to make up his coefficients
 *	are both wrong and out of date.  Brown did the same
 *	thing in a different way.
 */

	k1 = eccm/22639.500;
	k2 = eccs/.01675104;
	k3 = 1. + 2.708e-6 + .000108008*dgamma;
	k4 = cpe/125.154;
	k5 = chp/3422.700;

/*
 *	the principal arguments that are used to compute
 *	perturbations are the following differences of the
 *	fundamental elements.
 */

	mnom = dlong - argp;
	msun = lsun - psun;
	noded = dlong - node;
	dmoon = dlong - lsun;

/*
 *	solar terms in longitude
 */

	lterms = 0.0;
	mp = moontab;
	for(;;) {
		if(mp->f == 0.0)
			break;
		lterms += sinx(mp->f,
			mp->c[0], mp->c[1],
			mp->c[2], mp->c[3], 0.0);
		mp++;
	}
	mp++;

/*
 *	planetary terms in longitude
 */

	lterms += sinx(0.822, 0,0,0,0, t0-v0);
	lterms += sinx(0.307, 0,0,0,0, 2.*t0-2.*v0+179.8);
	lterms += sinx(0.348, 0,0,0,0, 3.*t0-2.*v0+272.9);
	lterms += sinx(0.176, 0,0,0,0, 4.*t0-3.*v0+271.7);
	lterms += sinx(0.092, 0,0,0,0, 5.*t0-3.*v0+199.);
	lterms += sinx(0.129, 1,0,0,0, -t0+v0+180.);
	lterms += sinx(0.152, 1,0,0,0, t0-v0);
	lterms += sinx(0.127, 1,0,0,0, 3.*t0-3.*v0+180.);
	lterms += sinx(0.099, 0,0,0,2, t0-v0);
	lterms += sinx(0.136, 0,0,0,2, 2.*t0-2.*v0+179.5);
	lterms += sinx(0.083, -1,0,0,2, -4.*t0+4.*v0+180.);
	lterms += sinx(0.662, -1,0,0,2, -3.*t0+3.*v0+180.0);
	lterms += sinx(0.137, -1,0,0,2, -2.*t0+2.*v0);
	lterms += sinx(0.133, -1,0,0,2, t0-v0);
	lterms += sinx(0.157, -1,0,0,2, 2.*t0-2.*v0+179.6);
	lterms += sinx(0.079, -1,0,0,2, -8.*t0+6.*v0+162.6);
	lterms += sinx(0.073, 2,0,0,-2, 3.*t0-3.*v0+180.);
	lterms += sinx(0.643, 0,0,0,0, -t0+j0+178.8);
	lterms += sinx(0.187, 0,0,0,0, -2.*t0+2.*j0+359.6);
	lterms += sinx(0.087, 0,0,0,0, j0+289.9);
	lterms += sinx(0.165, 0,0,0,0, -t0+2.*j0+241.5);
	lterms += sinx(0.144, 1,0,0,0, t0-j0+1.0);
	lterms += sinx(0.158, 1,0,0,0, -t0+j0+179.0);
	lterms += sinx(0.190, 1,0,0,0, -2.*t0+2.*j0+180.0);
	lterms += sinx(0.096, 1,0,0,0, -2.*t0+3.*j0+352.5);
	lterms += sinx(0.070, 0,0,0,2, 2.*t0-2.*j0+180.);
	lterms += sinx(0.167, 0,0,0,2, -t0+j0+178.5);
	lterms += sinx(0.085, 0,0,0,2, -2.*t0+2.*j0+359.2);
	lterms += sinx(1.137, -1,0,0,2, 2.*t0-2.*j0+180.3);
	lterms += sinx(0.211, -1,0,0,2, -t0+j0+178.4);
	lterms += sinx(0.089, -1,0,0,2, -2.*t0+2.*j0+359.2);
	lterms += sinx(0.436, -1,0,0,2, 2.*t0-3.*j0+7.5);
	lterms += sinx(0.240, 2,0,0,-2, -2.*t0+2.*j0+179.9);
	lterms += sinx(0.284, 2,0,0,-2, -2.*t0+3.*j0+172.5);
	lterms += sinx(0.195, 0,0,0,0, -2.*t0+2.*m0+180.2);
	lterms += sinx(0.327, 0,0,0,0, -t0+2.*m0+224.4);
	lterms += sinx(0.093, 0,0,0,0, -2.*t0+4.*m0+244.8);
	lterms += sinx(0.073, 1,0,0,0, -t0+2.*m0+223.3);
	lterms += sinx(0.074, 1,0,0,0, t0-2.*m0+306.3);
	lterms += sinx(0.189, 0,0,0,0, node+180.);

/*
 *	solar terms in latitude
 */

	sterms = 0;
	for(;;) {
		if(mp->f == 0)
			break;
		sterms += sinx(mp->f,
			mp->c[0], mp->c[1],
			mp->c[2], mp->c[3], 0);
		mp++;
	}
	mp++;

	cterms = 0;
	for(;;) {
		if(mp->f == 0)
			break;
		cterms += cosx(mp->f,
			mp->c[0], mp->c[1],
			mp->c[2], mp->c[3], 0);
		mp++;
	}
	mp++;

	nterms = 0;
	for(;;) {
		if(mp->f == 0)
			break;
		nterms += sinx(mp->f,
			mp->c[0], mp->c[1],
			mp->c[2], mp->c[3], 0);
		mp++;
	}
	mp++;

/*
 *	planetary terms in latitude
 */

	pterms =
		   sinx(0.215, 0,0,0,0, dlong);

/*
 *	solar terms in parallax
 */

	spterms = 3422.700;
	for(;;) {
		if(mp->f == 0)
			break;
		spterms += cosx(mp->f,
			mp->c[0], mp->c[1],
			mp->c[2], mp->c[3], 0);
		mp++;
	}

/*
 *	planetary terms in parallax
 */

	spterms = spterms;

/*
 *	computation of longitude
 */

	lambda = (dlong + lterms/3600.)*radian;

/*
 *	computation of latitude
 */

	arglat = (noded + sterms/3600.)*radian;
	gamma1 = 18519.700 * k3;
	gamma2 = -6.241 * k3*k3*k3;
	gamma3 = 0.004 * k3*k3*k3*k3*k3;

	k6 = (gamma1 + cterms) / gamma1;

	beta = k6 * (gamma1*sin(arglat) + gamma2*sin(3.*arglat)
		 + gamma3*sin(5.*arglat) + nterms)
		 + pterms;
	if(flags['o'])
		beta -= 0.6;
	beta *= radsec;

/*
 *	computation of parallax
 */

	spterms = k5 * spterms *radsec;
	hp = spterms + (spterms*spterms*spterms)/6.;

	rad = hp/radsec;
	rp = 1.;
	semi = .0799 + .272453*(hp/radsec);
	if(dmoon < 0.)
		dmoon += 360.;
	mag = dmoon/360.;

/*
 *	change to equatorial coordinates
 */

	lambda += phi;
	obl2 = obliq + eps;
	xmp = rp*cos(lambda)*cos(beta);
	ymp = rp*(sin(lambda)*cos(beta)*cos(obl2) - sin(obl2)*sin(beta));
	zmp = rp*(sin(lambda)*cos(beta)*sin(obl2) + cos(obl2)*sin(beta));

	alpha = atan2(ymp, xmp);
	delta = atan2(zmp, sqrt(xmp*xmp+ymp*ymp));
	meday = eday;
	mhp = hp;

	geo();
}