Beispiel #1
0
void ArchesModel::InitModel() {
    int NumArches=parm1;
    int SegmentsPerArch=parm2;
    arc = wxAtoi(ModelXml->GetAttribute("arc", "180"));

    
    SetBufferSize(NumArches,SegmentsPerArch);
    if (SingleNode) {
        SetNodeCount(NumArches * SegmentsPerArch, parm3,rgbOrder);
    } else {
        SetNodeCount(NumArches, SegmentsPerArch, rgbOrder);
        if (parm3 > 1) {
            for (int x = 0; x < Nodes.size(); x++) {
                Nodes[x]->Coords.resize(parm3);
            }
        }
    }
    screenLocation.SetRenderSize(SegmentsPerArch, NumArches);
    
    for (int y=0; y < NumArches; y++) {
        for(int x=0; x<SegmentsPerArch; x++) {
            int idx = y * SegmentsPerArch + x;
            Nodes[idx]->ActChan = stringStartChan[y] + x*GetNodeChannelCount(StringType);
            Nodes[idx]->StringNum=y;
            for(size_t c=0; c < GetCoordCount(idx); c++) {
                Nodes[idx]->Coords[c].bufX=IsLtoR ? x : SegmentsPerArch-x-1;
                Nodes[idx]->Coords[c].bufY=isBotToTop ? y : NumArches-y-1;
            }
        }
    }
    SetArchCoord();
}
Beispiel #2
0
// initialize buffer coordinates
// parm1=Number of Strings/Arches
// parm2=Pixels Per String/Arch
void ModelClass::InitLine()
{
    SetNodeCount(parm1,parm2);
    SetBufferSize(1,parm2);
    int LastStringNum=-1;
    int chan,idx;
    int ChanIncr=SingleChannel ?  1 : 3;
    size_t NodeCount=GetNodeCount();
    for(size_t n=0; n<NodeCount; n++)
    {
        if (Nodes[n]->StringNum != LastStringNum)
        {
            LastStringNum=Nodes[n]->StringNum;
            chan=stringStartChan[LastStringNum];
            idx=0;
        }
        Nodes[n]->ActChan=chan;
        chan+=ChanIncr;
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            Nodes[n]->Coords[c].bufX=IsLtoR ? idx : parm2-idx-1;
            Nodes[n]->Coords[c].bufY=0;
            idx++;
        }
    }
}
Beispiel #3
0
// initialize screen coordinates for tree
void ModelClass::SetTreeCoord(long degrees)
{
    int bufferX, bufferY;
    double angle,x0;
    TreeDegrees=degrees;
    if (BufferWi < 2) return;
    if(BufferHt<1) return; // June 27,2013. added check to not divide by zero
    int factor=1000/BufferHt;
    RenderHt=BufferHt*factor;
    RenderWi=RenderHt/2;
    double radians=toRadians(degrees);
    double radius=RenderWi/2.0;
    double StartAngle=-radians/2.0;
    double AngleIncr=radians/double(BufferWi-1);
    //wxString msg=wxString::Format("BufferHt=%d, BufferWi=%d, factor=%d, RenderHt=%d, RenderWi=%d\n",BufferHt,BufferWi,factor,RenderHt,RenderWi);
    size_t NodeCount=GetNodeCount();
    for(size_t n=0; n<NodeCount; n++)
    {
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            bufferX=Nodes[n]->Coords[c].bufX;
            bufferY=Nodes[n]->Coords[c].bufY;
            angle=StartAngle + double(bufferX) * AngleIncr;
            x0=radius * sin(angle);
            Nodes[n]->Coords[c].screenX=floor(x0*(1.0-double(bufferY)/double(BufferHt)) + 0.5);
            Nodes[n]->Coords[c].screenY=bufferY * factor;
        }
    }
}
Beispiel #4
0
// parm3 is number of points
// top left=top ccw, top right=top cw, bottom left=bottom cw, bottom right=bottom ccw
void ModelClass::InitStar()
{
    if (parm3 < 2) parm3=2; // need at least 2 arms
    SetNodeCount(parm1,parm2);
    int numlights=parm1*parm2;
    SetBufferSize(numlights+1,numlights+1);
    int LastStringNum=-1;
    int chan,cursegment,nextsegment,x,y;
    int offset=numlights/2;
    int numsegments=parm3*2;
    double segstart_x,segstart_y,segend_x,segend_y,segstart_pct,segend_pct,r,segpct,dseg;
    double dpct=1.0/(double)numsegments;
    double OuterRadius=offset;
    double InnerRadius=OuterRadius/2.618034;    // divide by golden ratio squared
    double pct=isBotToTop ? 0.5 : 0.0;          // % of circle, 0=top
    double pctIncr=1.0 / (double)numlights;     // this is cw
    if (IsLtoR != isBotToTop) pctIncr*=-1.0;    // adjust to ccw
    int ChanIncr=SingleChannel ?  1 : 3;
    size_t NodeCount=GetNodeCount();
    for(size_t n=0; n<NodeCount; n++)
    {
        if (Nodes[n]->StringNum != LastStringNum)
        {
            LastStringNum=Nodes[n]->StringNum;
            chan=stringStartChan[LastStringNum];
        }
        Nodes[n]->ActChan=chan;
        chan+=ChanIncr;
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            cursegment=(int)((double)numsegments*pct) % numsegments;
            nextsegment=(cursegment+1) % numsegments;
            segstart_pct=(double)cursegment / numsegments;
            segend_pct=(double)nextsegment / numsegments;
            dseg=pct - segstart_pct;
            segpct=dseg / dpct;
            r=cursegment%2==0 ? OuterRadius : InnerRadius;
            segstart_x=r*sin(segstart_pct*2.0*M_PI);
            segstart_y=r*cos(segstart_pct*2.0*M_PI);
            r=nextsegment%2==0 ? OuterRadius : InnerRadius;
            segend_x=r*sin(segend_pct*2.0*M_PI);
            segend_y=r*cos(segend_pct*2.0*M_PI);
            // now interpolate between segstart and segend
            x=(segend_x - segstart_x)*segpct + segstart_x + offset + 0.5;
            y=(segend_y - segstart_y)*segpct + segstart_y + offset + 0.5;
            Nodes[n]->Coords[c].bufX=x;
            Nodes[n]->Coords[c].bufY=y;
            pct+=pctIncr;
            if (pct >= 1.0) pct-=1.0;
            if (pct < 0.0) pct+=1.0;
        }
    }
}
Beispiel #5
0
int ModelClass::FindChannelAt(int x, int y)
{
    size_t NodeCount=GetNodeCount();
    for(size_t n=0; n<NodeCount; n++)
    {
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
//??            if ((Nodes[n]->Coords[c].screenX == x) && (Nodes[n]->Coords[c].screenY == y)) return Nodes[n].ActChan;
            if ((Nodes[n]->Coords[c].bufX == x) && (Nodes[n]->Coords[c].bufY == y)) return Nodes[n]->ActChan;
        }
    }
    return -1; //not found
}
Beispiel #6
0
// uses DrawCircle instead of DrawPoint
void ModelClass::DisplayEffectOnWindow(wxWindow* window)
{
    wxColour color;
    wxDouble w, h;

    ModelGraphics gc(window);
    gc.GetSize(&w, &h);

    double scaleX = double(w) * 0.95 / RenderWi;
    double scaleY = double(h) * 0.95 / RenderHt;
    double scale=scaleY < scaleX ? scaleY : scaleX;

    gc.Translate(w/2,-int(double(RenderHt)*scale + double(RenderHt)*0.025*scale));

    double radius = scale/2.0;
    if (radius < 0.5)
    {
        radius = 0.5;
    }

    /*
    // check that origin is in the right place
    color.Set(0,0,255);
    gc.AddCircle(color, 0,0,1);
    gc.AddCircle(color, 1,1,1);
    gc.AddCircle(color, 2,2,1);
    gc.AddCircle(color, 3,3,1);
    gc.AddCircle(color, 4,4,1);
     */

    // layer calculation and map to output
    size_t NodeCount=Nodes.size();
    double sx,sy;
    for(size_t n=0; n<NodeCount; n++)
    {
        Nodes[n]->GetColor(color);
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            // draw node on screen
            sx=Nodes[n]->Coords[c].screenX;
            sy=Nodes[n]->Coords[c].screenY;
            //#     dc.DrawPoint(Nodes[i].screenX, Nodes[i].screenY);
            //dc.DrawPoint(sx,sy);
            //dc.DrawCircle(sx*scale,sy*scale,radius);
            //gc->DrawEllipse(sx*scale,sy*scale,radius,radius);
            gc.AddCircle(color, sx*scale,sy*scale,radius);
        }
    }
}
Beispiel #7
0
// initialize screen coordinates
void ModelClass::CopyBufCoord2ScreenCoord()
{
    size_t NodeCount=GetNodeCount();
    int xoffset=BufferWi/2;
    for(size_t n=0; n<NodeCount; n++)
    {
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            Nodes[n]->Coords[c].screenX = Nodes[n]->Coords[c].bufX - xoffset;
            Nodes[n]->Coords[c].screenY = Nodes[n]->Coords[c].bufY;
        }
    }
    SetRenderSize(BufferHt,BufferWi);
}
Beispiel #8
0
// Set screen coordinates for arches
void ModelClass::SetArchCoord()
{
    int xoffset,x,y;
    int numlights=parm1*parm2;
    size_t NodeCount=GetNodeCount();
    SetRenderSize(parm2,numlights*2);
    double midpt=parm2;
    for(size_t n=0; n<NodeCount; n++)
    {
        xoffset=Nodes[n]->StringNum*parm2*2 - numlights;
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            double angle=-M_PI/2.0 + M_PI * (double)Nodes[n]->Coords[c].bufX/midpt;
            x=xoffset + (int)floor(midpt*sin(angle)+midpt);
            y=(int)floor(midpt*cos(angle)+0.5);
            Nodes[n]->Coords[c].screenX=x;
            Nodes[n]->Coords[c].screenY=y;
        }
    }
}
Beispiel #9
0
// initialize screen coordinates
// parm1=Number of Strings/Arches
// parm2=Pixels Per String/Arch
void ModelClass::SetLineCoord()
{
    int x,y;
    int idx=0;
    size_t NodeCount=GetNodeCount();
    int numlights=parm1*parm2;
    int half=numlights/2;
    SetRenderSize(numlights*2,numlights);
    double radians=toRadians(PreviewRotation);
    for(size_t n=0; n<NodeCount; n++)
    {
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            x=cos(radians)*idx;
            x=IsLtoR ? x - half : half - x;
            y=sin(radians)*idx;
            Nodes[n]->Coords[c].screenX=x;
            Nodes[n]->Coords[c].screenY=y + numlights;
            idx++;
        }
    }
}
Beispiel #10
0
void ArchesModel::SetArchCoord() {
    double xoffset,x,y;
    size_t NodeCount=GetNodeCount();
    double midpt=parm2*parm3;
    midpt -= 1.0;
    midpt /= 2.0;
    double total = toRadians(arc);
    double start = (M_PI - total) / 2.0;
    
    double angle=-M_PI/2.0 + start;
    x=midpt*sin(angle)*2.0+parm2*parm3;
    double width = parm2*parm3*2 - x;
    
    double minY = 999999;
    for(size_t n=0; n<NodeCount; n++) {
        xoffset=Nodes[n]->StringNum*width;
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++) {
            double angle=-M_PI/2.0 + start + total * ((double)(Nodes[n]->Coords[c].bufX * parm3 + c))/midpt/2.0;
            x=xoffset + midpt*sin(angle)*2.0+parm2*parm3;
            y=(parm2*parm3)*cos(angle);
            Nodes[n]->Coords[c].screenX=x;
            Nodes[n]->Coords[c].screenY=y;
            minY = std::min(minY, y);
        }
    }
    float renderHt = parm2*parm3;
    if (minY > 1) {
        renderHt -= minY;
        for (auto it = Nodes.begin(); it != Nodes.end(); it++) {
            for (auto coord = (*it)->Coords.begin(); coord != (*it)->Coords.end(); coord++) {
                coord->screenY -= minY;
            }
        }
    }
    screenLocation.SetRenderSize(width*parm1, renderHt);
}
Beispiel #11
0
// display model using a single color
void ModelClass::DisplayModelOnWindow(wxWindow* window, const wxColour* color)
{
    size_t NodeCount=Nodes.size();
    wxCoord sx,sy;
    wxPen pen;
    wxDouble w, h;
    ModelGraphics gc(window);

    /*
    // this isn't an ideal scaling algorithm - room for improvement here
    double windowDiagonal=sqrt(w*w+h*h);
    double modelDiagonal=sqrt(RenderWi*RenderWi+RenderHt*RenderHt);
    double scale=windowDiagonal / modelDiagonal * PreviewScale;
    */

    gc.GetSize(&w, &h);
    double scale=RenderHt > RenderWi ? double(h) / RenderHt * PreviewScale : double(w) / RenderWi * PreviewScale;
    double scrx,scry;
    gc.Translate(int(offsetXpct*w)+w/2,
                 -(int(offsetYpct*h)+h-
                   std::max((int(h)-int(double(RenderHt-1)*scale))/2,1)));

    for(size_t n=0; n<NodeCount; n++)
    {
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            // draw node on screen
            sx=Nodes[n]->Coords[c].screenX;
            sy=Nodes[n]->Coords[c].screenY;
            gc.AddSquare(*color,sx*scale,sy*scale,0.0);
            scrx = sx*scale;
            scry = sy*scale;
            //      StatusBar1->SetStatusText(_("Status: DisplayModelOnWindow " )+wxString::Format(" x=%5ld y=%5ld ",scrx,scry));
        }
    }
}
Beispiel #12
0
// top left=top ccw, top right=top cw, bottom left=bottom cw, bottom right=bottom ccw
void ModelClass::InitWreath()
{
    SetNodeCount(parm1,parm2);
    int numlights=parm1*parm2;
    SetBufferSize(numlights+1,numlights+1);
    int LastStringNum=-1;
    int offset=numlights/2;
    double r=offset;
    int chan,x,y;
    double pct=isBotToTop ? 0.5 : 0.0;          // % of circle, 0=top
    double pctIncr=1.0 / (double)numlights;     // this is cw
    if (IsLtoR != isBotToTop) pctIncr*=-1.0;    // adjust to ccw
    int ChanIncr=SingleChannel ?  1 : 3;
    size_t NodeCount=GetNodeCount();
    for(size_t n=0; n<NodeCount; n++)
    {
        if (Nodes[n]->StringNum != LastStringNum)
        {
            LastStringNum=Nodes[n]->StringNum;
            chan=stringStartChan[LastStringNum];
        }
        Nodes[n]->ActChan=chan;
        chan+=ChanIncr;
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            x=r*sin(pct*2.0*M_PI) + offset + 0.5;
            y=r*cos(pct*2.0*M_PI) + offset + 0.5;
            Nodes[n]->Coords[c].bufX=x;
            Nodes[n]->Coords[c].bufY=y;
            pct+=pctIncr;
            if (pct >= 1.0) pct-=1.0;
            if (pct < 0.0) pct+=1.0;
        }
    }
}
Beispiel #13
0
// initialize buffer coordinates
// parm1=Nodes on Top
// parm2=Nodes left and right
// parm3=Nodes on Bottom
void ModelClass::InitFrame()
{
    int x,y,newx,newy;
    SetNodeCount(1,parm1+2*parm2+parm3);
    int FrameWidth=std::max(parm1,parm3)+2;
    SetBufferSize(parm2,FrameWidth);   // treat as outside of matrix
    //SetBufferSize(1,Nodes.size());   // treat as single string
    SetRenderSize(parm2,FrameWidth);
    int chan=stringStartChan[0];
    int ChanIncr=SingleChannel ?  1 : 3;

    int xincr[4]= {0,1,0,-1}; // indexed by side
    int yincr[4]= {1,0,-1,0};
    x=IsLtoR ? 0 : FrameWidth-1;
    y=isBotToTop ? 0 : parm2-1;
    int dir=1;            // 1=clockwise
    int side=x>0 ? 2 : 0; // 0=left, 1=top, 2=right, 3=bottom
    int SideIncr=1;       // 1=clockwise
    if ((parm1 > parm3 && x>0) || (parm3 > parm1 && x==0))
    {
        // counter-clockwise
        dir=-1;
        SideIncr=3;
    }

    // determine starting position
    if (parm1 > parm3)
    {
        // more nodes on top, must start at bottom
        y=0;
    }
    else if (parm3 > parm1)
    {
        // more nodes on bottom, must start at top
        y=parm2-1;
    }
    else
    {
        // equal top and bottom, can start in any corner
        // assume clockwise numbering
        if (x>0 && y==0)
        {
            // starting in lower right
            side=3;
        }
        else if (x==0 && y>0)
        {
            // starting in upper left
            side=1;
        }
    }

    size_t NodeCount=GetNodeCount();
    for(size_t n=0; n<NodeCount; n++)
    {
        Nodes[n]->ActChan=chan;
        chan+=ChanIncr;
        size_t CoordCount=GetCoordCount(n);
        for(size_t c=0; c < CoordCount; c++)
        {
            Nodes[n]->Coords[c].bufX=x;
            Nodes[n]->Coords[c].bufY=y;
            newx=x+xincr[side]*dir;
            newy=y+yincr[side]*dir;
            if (newx < 0 || newx >= FrameWidth || newy < 0 || newy >= parm2)
            {
                // move to the next side
                side=(side+SideIncr) % 4;
                newx=x+xincr[side]*dir;
                newy=y+yincr[side]*dir;
            }
            x=newx;
            y=newy;
        }
    }
}
Beispiel #14
0
// display model using colors stored in each node
// used when preview is running
void ModelClass::DisplayModelOnWindow(wxWindow* window)
{
    size_t NodeCount=Nodes.size();
    wxCoord sx,sy;
    wxPen pen;
    wxColour color;
    wxDouble w, h;
    ModelGraphics gc(window);

    /*
    // this isn't an ideal scaling algorithm - room for improvement here
    double windowDiagonal=sqrt(w*w+h*h);
    double modelDiagonal=sqrt(RenderWi*RenderWi+RenderHt*RenderHt);
    double scale=windowDiagonal / modelDiagonal * PreviewScale;
    */

    gc.GetSize(&w, &h);
    double scale=RenderHt > RenderWi ? double(h) / RenderHt * PreviewScale : double(w) / RenderWi * PreviewScale;
    gc.Translate(int(offsetXpct*w)+w/2,
                 -(int(offsetYpct*h)+h-
                   std::max((int(h)-int(double(RenderHt-1)*scale))/2,1)));

    // avoid performing StrobeRate test in inner loop for performance reasons
    if (StrobeRate==0)
    {
        // no strobing
        for(size_t n=0; n<NodeCount; n++)
        {
            Nodes[n]->GetColor(color);
            size_t CoordCount=GetCoordCount(n);
            for(size_t c=0; c < CoordCount; c++)
            {
                // draw node on screen
                sx=Nodes[n]->Coords[c].screenX;
                sy=Nodes[n]->Coords[c].screenY;
                gc.AddSquare(color,sx*scale,sy*scale,0.0);
            }
        }
    }
    else
    {
        // flash individual nodes according to StrobeRate
        for(size_t n=0; n<NodeCount; n++)
        {
            Nodes[n]->GetColor(color);
            bool CanFlash = color.GetRGB() ==  0x00ffffff;
            size_t CoordCount=GetCoordCount(n);
            for(size_t c=0; c < CoordCount; c++)
            {
                wxColor c2 = *wxBLACK;
                // draw node on screen
                if (CanFlash && rand() % StrobeRate == 0)
                {
                    c2 = color;
                }

                sx=Nodes[n]->Coords[c].screenX;
                sy=Nodes[n]->Coords[c].screenY;
                gc.AddSquare(c2,sx*scale,sy*scale,0.0);
            }
        }
    }
}
Beispiel #15
0
// initialize screen coordinates for tree
void TreeModel::SetTreeCoord(long degrees) {
    double bufferX, bufferY;
    if (BufferWi < 1) return;
    if (BufferHt < 1) return; // June 27,2013. added check to not divide by zero
    double RenderHt, RenderWi;
    if (degrees > 0) {
        double angle;
        RenderHt=BufferHt * 3;
        RenderWi=((double)RenderHt)/1.8;
        
        double radians=toRadians(degrees);
        double radius=RenderWi/2.0;
        double topradius=radius/botTopRatio;
        
        double StartAngle=-radians/2.0;
        double AngleIncr=radians/double(BufferWi);
        if (degrees < 350 && BufferWi > 1) {
            AngleIncr=radians/double(BufferWi - 1);
        }
        
        //shift a tiny bit to make the strands in back not line up exactly with the strands in front
        StartAngle += toRadians(rotation);
        
        std::vector<float> yPos(BufferHt);
        std::vector<float> xInc(BufferHt);
        for (int x = 0; x < BufferHt; x ++) {
            yPos[x] = x;
            xInc[x] = 0;
        }
        if (spiralRotations != 0.0f) {
            std::vector<float> lengths(10);
            float rgap = (radius - topradius)/ 10.0;
            float total = 0;
            for (int x = 0; x < 10; x++) {
                lengths[x] = 2.0*M_PI*(radius - rgap*x) - rgap/2.0;
                lengths[x] *= spiralRotations / 10.0;
                lengths[x] = sqrt(lengths[x]*lengths[x]+(float)BufferHt/10.0*(float)BufferHt/10.0);
                total += lengths[x];
            }
            int lights = 0;
            for (int x = 0; x < 10; x++) {
                lengths[x] /= total;
                lights += (int)std::round(lengths[x]*BufferHt);
            }
            int curSeg = 0;
            float lightsInSeg = std::round(lengths[0]*BufferHt);
            int curLightInSeg = 0;
            for (int x = 1; x < BufferHt; x++) {
                if (curLightInSeg >= lightsInSeg) {
                    curSeg++;
                    curLightInSeg = 0;
                    lightsInSeg = std::round(lengths[curSeg]*BufferHt);
                }
                float ang = spiralRotations * 2.0 * M_PI / 10.0;
                ang /= (float)lightsInSeg;
                yPos[x] = yPos[x-1] + (BufferHt/10.0/lightsInSeg);
                xInc[x] = xInc[x-1] + ang;
                curLightInSeg++;
            }
        }
        
        
        double topYoffset = std::abs(perspective * topradius * cos(M_PI));
        double ytop = RenderHt - topYoffset;
        double ybot = std::abs(perspective * radius * cos(M_PI));
        
        size_t NodeCount=GetNodeCount();
        for(size_t n=0; n<NodeCount; n++) {
            size_t CoordCount=GetCoordCount(n);
            for(size_t c=0; c < CoordCount; c++) {
                bufferX=Nodes[n]->Coords[c].bufX;
                bufferY=Nodes[n]->Coords[c].bufY;
                angle=StartAngle + double(bufferX) * AngleIncr + xInc[bufferY];
                double xb=radius * sin(angle);
                double xt=topradius * sin(angle);
                double yb = ybot - perspective * radius * cos(angle);
                double yt = ytop - perspective * topradius * cos(angle);
                double posOnString = 0.5;
                if (BufferHt > 1) {
                    posOnString = yPos[bufferY]/(double)(BufferHt-1.0);
                }

                Nodes[n]->Coords[c].screenX = xb + (xt - xb) * posOnString;
                Nodes[n]->Coords[c].screenY = yb + (yt - yb) * posOnString - ((double)RenderHt)/2.0;
            }
        }
    } else {
        double treeScale = degrees == -1 ? 5.0 : 4.0;
        double botWid = BufferWi * treeScale;
        RenderHt=BufferHt * 2.0;
        RenderWi=(botWid + 2);
        
        double offset = 0.5;
        size_t NodeCount=GetNodeCount();
        for(size_t n=0; n<NodeCount; n++) {
            size_t CoordCount=GetCoordCount(n);
            if (degrees == -1) {
                for(size_t c=0; c < CoordCount; c++) {
                    bufferX=Nodes[n]->Coords[c].bufX;
                    bufferY=Nodes[n]->Coords[c].bufY;
                    
                    double xt = (bufferX + offset - BufferWi/2.0) * 0.9;
                    double xb = (bufferX + offset - BufferWi/2.0) * treeScale;
                    double h = std::sqrt(RenderHt * RenderHt + (xt - xb)*(xt - xb));
                    
                    double posOnString = 0.5;
                    if (BufferHt > 1) {
                        posOnString = (bufferY/(double)(BufferHt-1.0));
                    }
                    
                    double newh = RenderHt * posOnString;
                    Nodes[n]->Coords[c].screenX = xb + (xt - xb) * posOnString;
                    Nodes[n]->Coords[c].screenY = RenderHt * newh / h - ((double)RenderHt)/2.0;
                    
                    posOnString = 0;
                    if (BufferHt > 1) {
                        posOnString = ((bufferY - 0.33)/(double)(BufferHt-1.0));
                    }

                    newh = RenderHt * posOnString;
                    Nodes[n]->Coords.push_back(Nodes[n]->Coords[c]);
                    Nodes[n]->Coords.back().screenX = xb + (xt - xb) * posOnString;
                    Nodes[n]->Coords.back().screenY = RenderHt * newh / h - ((double)RenderHt)/2.0;
                    
                    posOnString = 1;
                    if (BufferHt > 1) {
                        posOnString = ((bufferY + 0.33)/(double)(BufferHt-1.0));
                    }
                    newh = RenderHt * posOnString;
                    Nodes[n]->Coords.push_back(Nodes[n]->Coords[c]);
                    Nodes[n]->Coords.back().screenX = xb + (xt - xb) * posOnString;
                    Nodes[n]->Coords.back().screenY = RenderHt * newh / h - ((double)RenderHt)/2.0;
                }
                
            } else {
                for(size_t c=0; c < CoordCount; c++) {
                    bufferX=Nodes[n]->Coords[c].bufX;
                    bufferY=Nodes[n]->Coords[c].bufY;
                    
                    double xt = (bufferX + offset - BufferWi/2.0) * 0.9;
                    double xb = (bufferX + offset - BufferWi/2.0) * treeScale;
                    double posOnString = 0.5;
                    if (BufferHt > 1) {
                        posOnString = (bufferY/(double)(BufferHt-1.0));
                    }
                    Nodes[n]->Coords[c].screenX = xb + (xt - xb) * posOnString;
                    Nodes[n]->Coords[c].screenY = RenderHt * posOnString - ((double)RenderHt)/2.0;
                }
            }
        }
    }
    screenLocation.SetRenderSize(RenderWi, RenderHt);
}