Computational routine
eng


vectorscopexy41

File content


/* Modnumlib Scicos interfacing function
 * Copyright (C) 2009-2011 Alan Layec
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
 
/* vectorscope xy Scicos Trajectory scope block
 *
 * - Based on Scilab NG routines
 *
 * Type 4 simulation function ver 1.0 - scilab-4.1
 * 24 mai 2007 - INRIA - Author : A.Layec
 */

/* REVISION HISTORY :
 * $Log$
 */

/*Standarc C include*/
#include <stdio.h>
#include <string.h>
/*#include <../include/math.h>*/

/*for NG*/
#include "SetProperty.h"
#include "GetProperty.h"
#include "InitObjects.h"
#include "bcg.h"
#include "DrawObjects.h"
#include "BuildObjects.h"
#include "ObjectStructure.h"
#include "DestroyObjects.h"

/*Scicos block st include*/
#include "scicos_block.h"

/*Scilab include*/
#include "machine.h"

/*some macros*/
#ifndef min
 #define min(a,b) ((a) <= (b) ? (a) : (b))
#endif

#ifndef max
#define max(a,b) ((a) >= (b) ? (a) : (b))
#endif

#define PI0 (integer *) 0
#define PD0 (double *) 0

#define Abs(x) ( ( (x) >= 0) ? (x) : -( x) )

/*external functions*/
extern integer C2F(dr1)();
extern integer C2F(xgrid)();

/*work structure of that block*/
typedef struct work_st {
  long   hdl;    /*hdl of the NG scope*/
  int    wid;    /*wid of the NG scope*/
  /*x axis autoscale variables*/
  double x_up;
  double x_down;
  double x_delta;
  /*y axis autoscale variables*/
  double y_up;
  double y_down;
  double y_delta;
} work_struct;

/*  vectorscopexy_draw :
 *  Initialization and re-initialization
 *   of the vectorscopexy block
 */
void vectorscopexy_draw(scicos_block *block)
{
 /*"fouretout" variables*/
 int i,j;

 /*variables to get rpar/ipar ptr*/
 double *rpar;
 int    *ipar;

 /*variables to store main paramaters*/
 double xmin, xmax;
 double ymin, ymax;

 /*graphic ptr variables*/
 char wnam[100];
 char x_label[30];
 char y_label[30];

 sciPointObj *pTemp;
 sciPointObj *pTemp2;
 sciPointObj *pPolyline;

 double *x_vect;
 double *y_vect;

 /*scope variables*/
 int nsubwin    =  1;
 int ncurves    =  1;
 int color      =  1;
 int line_size  =  1;
 int dim        =  2;

 int win_pos[2] = {-1,-1};
 int win_dim[2] = {-1,-1};

 int wid; /*the windows id*/
 int nvec;
 int insz;
 int isline;

 /*ptr of the struct of that block*/
 work_struct *work;

 /*get size of input ports*/
 insz = block->insz[0];

 /*get he struct of that block*/
 work     = (work_struct*) *block->work;

 /*get rpar/ipar*/
 rpar = block->rpar;
 ipar = block->ipar;

 wid    = ipar[0];
 nvec   = ipar[1]; /*number of vectors*/
 isline = ipar[4];

 win_dim[0] = ipar[5];
 win_dim[1] = ipar[6];

 ymin    = rpar[0];
 ymax    = rpar[1];
 xmin    = rpar[2];
 xmax    = rpar[3];

 /* get wid of the scope
  * and store it in my_st*/
 if (wid<0) {
   work->wid = 20000 + get_block_number();
 }
 else {
   work->wid = wid;
 }

 /* set title and axes labels of the scope
  */
 sprintf(wnam,"Vector XY Scope (%d)",work->wid);
 /* axis labels */
 sprintf(x_label,"Level"); /*x axis*/

 sprintf(y_label,"Level");

 /* Alocation/initialization of temporary x/y vectors
  * to build polyline
  */
 if ((x_vect=(double*)
       scicos_malloc(sizeof(double)*(insz))) == NULL) {
        set_block_error(-16); return;
 }
 if ((y_vect=(double*)
       scicos_malloc(sizeof(double)*(insz))) == NULL) {
        set_block_error(-16); return;
 }

 /* init NG scope
  */
 DeleteObjs(work->wid);
 sciSetUsedWindow(work->wid);
 pTemp = sciGetCurrentFigure();
 sciSetName(pTemp,wnam,strlen(wnam));
 pTemp2 = sciGetPointerFromHandle(sciGetHandle(sciGetSelectedSubWin(pTemp)));
 sciSetFontDeciWidth(pTemp2, 0);
 sciSetIsBoxed(pTemp2,TRUE);
 pSUBWIN_FEATURE(pTemp2)->tight_limits = TRUE;
 pSUBWIN_FEATURE(pTemp2)->WRect[0] = 0;
 pSUBWIN_FEATURE(pTemp2)->WRect[1] = 0;
 pSUBWIN_FEATURE(pTemp2)->WRect[2] = 1;
 pSUBWIN_FEATURE(pTemp2)->WRect[3] = 1;
 pSUBWIN_FEATURE(pTemp2)->axes.axes_visible[1] = TRUE;
 pSUBWIN_FEATURE(pTemp2)->SRect[2] = ymin;
 pSUBWIN_FEATURE(pTemp2)->SRect[3] = ymax;
 pSUBWIN_FEATURE(pTemp2)->axes.axes_visible[0] = TRUE;
 pSUBWIN_FEATURE(pTemp2)->SRect[0] = xmin;
 pSUBWIN_FEATURE(pTemp2)->SRect[1] = xmax;
 sciSetUsedWindow(work->wid);

 for(i=0;i<nvec;i++) {

   for(j=0;j<insz;j++) { /*init*/
     x_vect[j] = 0;
     y_vect[j] = 0;
   }

   pPolyline=ConstructPolyline(pTemp2,x_vect,y_vect,NULL,0,insz,1,1, \
                                 NULL,NULL,NULL,NULL,NULL,FALSE,FALSE,TRUE,FALSE);

   pPOLYLINE_FEATURE(pPolyline)->n1 = insz;
   sciSetIsClipping(pPolyline, 0);

   if (isline==1) {
     sciSetForeground(pPolyline, i+1);
     sciSetIsLine(pPolyline, 1);
     sciSetIsMark(pPolyline, 0);
   }
   else {
     sciSetMarkForeground(pPolyline, i+1);
     sciSetIsLine(pPolyline, 0);
     sciSetIsMark(pPolyline, 1);
   }

   sciSetMarkStyle(pPolyline, 0);
   sciSetMarkSizeUnit(pPolyline, 1);
   sciSetLineWidth(pPolyline,line_size);
   sciSetMarkSize(pPolyline,2);
 }

 sciSetText(pSUBWIN_FEATURE(pTemp2)->mon_x_label,x_label,500);
 sciSetFontDeciWidth(pSUBWIN_FEATURE(pTemp2)->mon_x_label, 0);
 sciSetText(pSUBWIN_FEATURE(pTemp2)->mon_y_label,y_label,500);
 sciSetFontDeciWidth(pSUBWIN_FEATURE(pTemp2)->mon_y_label, 0);

 if (win_dim[0] >= 0) {
   sciSetDim(pTemp,  &win_dim[0], &win_dim[1]);
   sciSetDim(pTemp2, &win_dim[0], &win_dim[1]);
 }

 C2F(xgrid)((i=12,&i)); /*show grid*/
 sciDrawObj(pTemp); /*draw scope*/

 /*store hld in work_st to know if window has been closed
  * during simulation
  */
 work->hdl = sciGetHandle(pTemp);

 /*free vectors no more needed*/
 scicos_free(x_vect);
 scicos_free(y_vect);

 /***** end of the display part ****/
}

/* main routine */
void vectorscopexy41(scicos_block *block,int flag)
{
 /*"fouretout" variables*/
 int i,k;

 double zero=0.0;

 /*variables to get block ptr*/
 int *ipar;
 double *u1;
 double *u2;

 /*ptr of the struct of that block*/
 work_struct *work;

 /*counters and indicies variables*/
 int nvec;
 int cnt_nvec;
 int insz;

 /*some scope parameters*/
 int scaltyp_y; /*0:ymin/ymax/1:autoscale*/
 int scaltyp_x; /*0:xmin/xmax/1:autoscale*/

 /*autoscale variables*/
 double min_y;
 double max_y;
 double min_x;
 double max_x;
 double y_height;
 double y_delta;
 double y_up;
 double y_down;
 double x_height;
 double x_delta;
 double x_up;
 double x_down;
 double fact=0.4;

 /*graphic ptr variables*/
 sciPointObj *pTemp;
 sciPointObj *pTemp2;
 sciPointObj *pPolyline;
 sciSons *MySon;

 /*get block ptr*/
 ipar = block->ipar;
 u1   = block->inptr[0];
 u2   = block->inptr[1];

 /*get ipar variables*/
 nvec = ipar[1]; /*number of vector*/
 scaltyp_y = ipar[2];
 scaltyp_x = ipar[3];

 /*ptr of the struct of that block*/
 work   = (work_struct*) *block->work;

 /*get size of input ports*/
 insz = block->insz[0];

 /*get counters value*/
 cnt_nvec = (int)block->z[0];

 if(flag==4) { /*flag 4*/

  if ((work=(work_struct*) /*my_st*/
        scicos_malloc(sizeof(work_struct))) == NULL) {
         set_block_error(-16); return;
  }

  /*init. autoscale y axis bound*/
  work->y_up=1;
  work->y_down=0;
  work->y_delta=1;

  /*init. autoscale x axis bound*/
  work->x_up=1;
  work->x_down=0;
  work->x_delta=1;

  *block->work=(void *)work; /*store my_st in *block->work*/

  vectorscopexy_draw(block); /*call vectorscope_draw for initialization*/
 }

 else if(flag==2) { /*flag 2*/

  cnt_nvec++;

  /*if window has been destroyed, then redraw it*/
  if (sciGetPointerFromHandle(work->hdl) == NULL) {
      vectorscopexy_draw(block);
  }

  sciSetUsedWindow(work->wid);
  pTemp = sciGetCurrentFigure();
  pTemp2 = sciGetPointerFromHandle(sciGetHandle(sciGetSelectedSubWin(pTemp)));
  MySon = (sciGetRelationship (pTemp2)->psons);

  /*autoscale*/
  if (scaltyp_x==1) {
    min_x = u1[0];
    max_x = min_x;
  }
  if (scaltyp_y==1) {
    min_y = u2[0];
    max_y = min_y;
   }

  /*choose good polyline*/
  for(i=nvec;i>cnt_nvec-1;i--) {
     pPolyline = MySon->pointobj;
     MySon = MySon->pnext;
  }

  if ((scaltyp_x==1)||(scaltyp_y==1)) {
    for(k=0;k<insz;k++) {
       pPOLYLINE_FEATURE(pPolyline)->pvx[k] = u1[k];
       pPOLYLINE_FEATURE(pPolyline)->pvy[k] = u2[k];
       if (scaltyp_x==1) {
         min_x=min(min_x,pPOLYLINE_FEATURE(pPolyline)->pvx[k]);
         max_x=max(max_x,pPOLYLINE_FEATURE(pPolyline)->pvx[k]);
       }
       if (scaltyp_y==1) {
         min_y=min(min_y,pPOLYLINE_FEATURE(pPolyline)->pvy[k]);
         max_y=max(max_y,pPOLYLINE_FEATURE(pPolyline)->pvy[k]);
       }
    }

    if (scaltyp_x==1) {
      x_height = max_x - min_x;
      x_delta  = min_x + x_height/2; /*also equal to max_x-x_height/2*/
      x_down   = x_delta - (1+fact) * x_height/2;
      y_up     = y_delta + (1+fact) * y_height/2;

      if ( (((1+fact) * x_height/2) > (1+fact) * work->x_delta) || \
           (((1+fact) * x_height/2) < (1-fact) * work->x_delta) ) {
         work->x_delta = ( (1+fact) * x_height/2);
         work->x_up = x_up;
         work->x_down = x_down;
      }

      pSUBWIN_FEATURE(pTemp2)->SRect[0] = work->x_down;
      pSUBWIN_FEATURE(pTemp2)->SRect[1] = work->x_up;
    }

    if (scaltyp_y==1) {
      y_height = max_y - min_y;
      y_delta  = min_y + y_height/2; /*also equal to max_y-y_height/2*/
      y_down   = y_delta - (1+fact) * y_height/2;
      y_up     = y_delta + (1+fact) * y_height/2;

      if ( (((1+fact) * y_height/2) > (1+fact) * work->y_delta) || \
           (((1+fact) * y_height/2) < (1-fact) * work->y_delta) ) {
         work->y_delta = ( (1+fact) * y_height/2);
         work->y_up = y_up;
         work->y_down = y_down;
      }

      pSUBWIN_FEATURE(pTemp2)->SRect[2] = work->y_down;
      pSUBWIN_FEATURE(pTemp2)->SRect[3] = work->y_up;
    }
  }
  else {
    for(k=0;k<insz;k++) {
       pPOLYLINE_FEATURE(pPolyline)->pvx[k] = u1[k];
       pPOLYLINE_FEATURE(pPolyline)->pvy[k] = u2[k];
    }
  }

  if (cnt_nvec == nvec){
    sciDrawObj(pTemp2); /*draw axes*/
    /*miscellaenous part to disable glitter of scope*/
    C2F(dr1)("xset","wwpc",PI0,PI0,PI0,PI0,PI0,PI0, \
                PD0,PD0,PD0,PD0,0L,0L);  /*clear pixmap*/
    pFIGURE_FEATURE(pTemp)->pixmap=1; /*set pixmap mode*/
    C2F(xgrid)((i=12,&i)); /*draw grid in the pixmap*/
    C2F(dr1)("xset","wshow",PI0,PI0,PI0,PI0,PI0,PI0, \
              PD0,PD0,PD0,PD0,0L,0L); /*show the pixmap*/
    pFIGURE_FEATURE(pTemp)->pixmap = 0; /*unset pixmap mode*/

    /*reset counter*/
    cnt_nvec = 0;
  }

  /*save counter an index values in dstate*/
  block->z[0] = (double)cnt_nvec;

 }

 else if (flag==5) { /*flag 5*/
  scicos_free(work);
 }

}