void TSensorView::LineViewer(TDC& dc,PSHORTREAL pData)
{
  m_xSize = m_nDimSize[0]-1;
  m_ySize = m_nDimSize[1]-1;
  m_yAdd = (int) (500L * m_ySize / m_xSize / 2);
  dc.SetWindowExt(TSize(m_xSize * 2 +  m_ySize,500 + m_yAdd));
  Grid3D(dc);
  if(m_nDimSize[1] == 1)
    for(int x = 0; x < m_nDimSize[0]; x++)
    {
      TPoint pt = Project2D(x,0,pData[x]);
      if (x)
        LINE(dc,pt);
      else
        MOVE(dc,pt);
    }
  else
  {
    TBrush br(SYSCOLOR(COLOR_BTNFACE));
    dc.SelectObject(br);
    for (int y = 0; y < m_nDimSize[1]-1; y++)
      for (int x = 0; x < m_nDimSize[0]-1; x++)
      {
        TPoint pt[4] =
        {
          Project2D(x,y,pData[x + (LONGINT) m_nDimSize[0] * y]),
          Project2D(x+1,y,pData[x+1 + (LONGINT) m_nDimSize[0] * y]),
          Project2D(x+1,y+1,pData[x+1 + (LONGINT) m_nDimSize[0] * (y+1)]),
          Project2D(x,y+1,pData[x + (LONGINT) m_nDimSize[0] * (y+1)])
        };
        POLY(dc,pt,4);
      }
  }
  dc.RestorePen();
}
Beispiel #2
0
// finds the complex roots of the polynomial
//  _p      :   polynomial array, ascending powers [size: _k x 1]
//  _k      :   polynomials length (poly order = _k - 1)
//  _roots  :   resulting complex roots [size: _k-1 x 1]
void POLY(_findroots)(T *          _p,
                      unsigned int _k,
                      TC *         _roots)
{
    // find roots of polynomial using Bairstow's method (more
    // accurate and reliable than Durand-Kerner)
    POLY(_findroots_bairstow)(_p,_k,_roots);
}
void TSensorView::ColumnViewer(TDC& dc,PSHORTREAL pData)
{
  m_xSize = m_nDimSize[0];
  m_ySize = m_nDimSize[1];
  m_yAdd = (int) (500L * m_ySize / m_xSize / 2);
  dc.SetWindowExt(TSize(m_xSize * 2 +  m_ySize,500 + m_yAdd));
  Grid3D(dc);
  TBrush brGray(SYSCOLOR(COLOR_BTNFACE)),
			brWhite(SYSCOLOR(COLOR_BTNHIGHLIGHT)),
			brDark(SYSCOLOR(COLOR_BTNSHADOW));
  for (int y = 0; y < m_nDimSize[1]; y++)
    for (int x = 0; x < m_nDimSize[0]; x++)
    {
      SHORTREAL r = pData[x + (LONGINT) m_nDimSize[0] * y];
      TPoint pt[4] =
      {
        Project2D(x,y+1,r),
        Project2D(x+1,y+1,r),
        Project2D(x+1,y,r),
        Project2D(x,y,r)
      };
      dc.SelectObject(brWhite);
      POLY(dc,pt,4);
      SHORTREAL r2 = y == m_nDimSize[1]-1
                     ? 0
                     : pData[x + (LONGINT) m_nDimSize[0] * (y+1)];
      if(r2 < r)
      {
        pt[2] = Project2D(x+1,y+1,r2);
        pt[3] = Project2D(x,y+1,r2);
        dc.SelectObject(brGray);
        POLY(dc,pt,4);
      }
      r2 = x == m_nDimSize[0]-1 ? 0
                  : pData[x+1 + (LONGINT) m_nDimSize[0] * y];
      if (r2 < r)
      {
        pt[0] = Project2D(x+1,y,r);
        pt[2] = Project2D(x+1,y+1,r2);
        pt[3] = Project2D(x+1,y,r2);
        dc.SelectObject(brDark);
        POLY(dc,pt,4);
      }
    }
  dc.RestoreBrush();
}
// finds the complex roots of the polynomial using the Durand-Kerner method
//  _p      :   polynomial array, ascending powers [size: _k x 1]
//  _k      :   polynomials length (poly order = _k - 1)
//  _roots  :   resulting complex roots [size: _k-1 x 1]
void POLY(_findroots_durandkerner)(T * _p,
                                   unsigned int _k,
                                   TC * _roots)
{
    if (_k < 2) {
        fprintf(stderr,"%s_findroots_durandkerner(), order must be greater than 0\n", POLY_NAME);
        exit(1);
    } else if (_p[_k-1] != 1) {
        fprintf(stderr,"%s_findroots_durandkerner(), _p[_k-1] must be equal to 1\n", POLY_NAME);
        exit(1);
    }

    unsigned int i;
    unsigned int num_roots = _k-1;
    T r0[num_roots];
    T r1[num_roots];

    // find intial magnitude
    float g     = 0.0f;
    float gmax  = 0.0f;
    for (i=0; i<_k; i++) {
        g = cabsf(_p[i]);
        if (i==0 || g > gmax)
            gmax = g;
    }

    // initialize roots
    T t0 = 0.9f * (1 + gmax) * cexpf(_Complex_I*1.1526f);
    T t  = 1.0f;
    for (i=0; i<num_roots; i++) {
        r0[i] = t;
        t *= t0;
    }

    unsigned int max_num_iterations = 50;
    int continue_iterating = 1;
    unsigned int j, k;
    T f;
    T fp;
    //for (i=0; i<num_iterations; i++) {
    i = 0;
    while (continue_iterating) {
#if 0
        printf("%s_findroots(), i=%3u :\n", POLY_NAME, i);
        for (j=0; j<num_roots; j++)
            printf("  r[%3u] = %12.8f + j*%12.8f\n", j, crealf(r0[j]), cimagf(r0[j]));
#endif
        for (j=0; j<num_roots; j++) {
            f = POLY(_val)(_p,_k,r0[j]);
            fp = 1;
            for (k=0; k<num_roots; k++) {
                if (k==j) continue;
                fp *= r0[j] - r0[k];
            }
            r1[j] = r0[j] - f / fp;
        }

        // stop iterating if roots have settled
        float delta=0.0f;
        T e;
        for (j=0; j<num_roots; j++) {
            e = r0[j] - r1[j];
            delta += crealf(e*conjf(e));
        }
        delta /= num_roots * gmax;
#if 0
        printf("delta[%3u] = %12.4e\n", i, delta);
#endif

        if (delta < 1e-6f || i == max_num_iterations)
            continue_iterating = 0;

        memmove(r0, r1, num_roots*sizeof(T));
        i++;
    }

    for (i=0; i<_k; i++)
        _roots[i] = r1[i];
}
// finds the complex roots of the polynomial
//  _p      :   polynomial array, ascending powers [size: _k x 1]
//  _k      :   polynomials length (poly order = _k - 1)
//  _roots  :   resulting complex roots [size: _k-1 x 1]
void POLY(_findroots)(T * _p,
                      unsigned int _k,
                      TC * _roots)
{
    POLY(_findroots_bairstow)(_p,_k,_roots);
}
// finds the complex roots of the polynomial using Bairstow's method
//  _p      :   polynomial array, ascending powers [size: _k x 1]
//  _k      :   polynomials length (poly order = _k - 1)
//  _roots  :   resulting complex roots [size: _k-1 x 1]
void POLY(_findroots_bairstow)(T * _p,
                               unsigned int _k,
                               TC * _roots)
{
    T p0[_k];       // buffer 0
    T p1[_k];       // buffer 1
    T * p   = NULL; // input polynomial
    T * pr  = NULL; // output (reduced) polynomial

    unsigned int i;
    unsigned int k=0;   // output roots counter
    memmove(p0, _p, _k*sizeof(T));

    T u, v;

    unsigned int n = _k;        // input counter (decrementer)
    unsigned int r = _k % 2;    // polynomial length odd? (order even?)
    unsigned int L = (_k-r)/2;  // semi-length
    for (i=0; i<L-1+r; i++) {
        // set polynomial and reduced polynomial buffer pointers
        p  = (i % 2) == 0 ? p0 : p1;
        pr = (i % 2) == 0 ? p1 : p0;

        // initial estimates for u, v
        // TODO : ensure no division by zero
        if (p[n-1] == 0) {
            fprintf(stderr,"warning: poly_findroots_bairstow(), irreducible polynomial");
            p[n-1] = 1e-12;
        }
        u = p[n-2] / p[n-1];
        v = p[n-3] / p[n-1];

        // compute factor using Bairstow's recursion
        POLY(_findroots_bairstow_recursion)(p,n,pr,&u,&v);

        // compute complex roots of x^2 + u*x + v
        TC r0 = 0.5f*(-u + csqrtf(u*u - 4.0*v));
        TC r1 = 0.5f*(-u - csqrtf(u*u - 4.0*v));

        // append result to output
        _roots[k++] = r0;
        _roots[k++] = r1;

#if 0
        // print debugging info
        unsigned int j;
        printf("initial polynomial:\n");
        for (j=0; j<n; j++)
            printf("  p[%3u]  = %12.8f + j*%12.8f\n", j, crealf(p[j]), cimagf(p[j]));

        printf("polynomial factor: x^2 + u*x + v\n");
        printf("  u : %12.8f + j*%12.8f\n", crealf(u), cimagf(u));
        printf("  v : %12.8f + j*%12.8f\n", crealf(v), cimagf(v));

        printf("roots:\n");
        printf("  r0 : %12.8f + j*%12.8f\n", crealf(r0), cimagf(r0));
        printf("  r1 : %12.8f + j*%12.8f\n", crealf(r1), cimagf(r1));

        printf("reduced polynomial:\n");
        for (j=0; j<n-2; j++)
            printf("  pr[%3u] = %12.8f + j*%12.8f\n", j, crealf(pr[j]), cimagf(pr[j]));
#endif

        // decrement new (reduced) polynomial size by 2
        n -= 2;
    }

    if (r==0) {
        assert(n==2);
        _roots[k++] = -pr[0]/pr[1];
    }
    //assert( k == _k-1 );
}
Beispiel #7
0
/* This gets called whenever the input, the size, changes. Create a cube with the given side length. */
static PComputeStatus compute(PPInput *input, PPOutput output, void *state)
{
	enum { MY_OBJECT, MY_GEOMETRY };			/* Node labels. */
	PONode		*obj, *geo;
	real32		radius = p_input_real32(input[0]);	/* Read out the radius. */
	uint32		end_splits = p_input_uint32(input[1]);	/* And the top/bottom tesselation level. */
	uint32		side_splits = p_input_uint32(input[2]);	/* And the side tesselation level. */
	uint32		quad_levels;
	boolean		uv_map = p_input_boolean(input[3]);
	real64		angle, y, r;
	uint32		i, j, pos, bc, tc;
	PNGLayer	*lay, *ulay, *vlay;

	if(side_splits < 2)
		return P_COMPUTE_DONE;

	obj = p_output_node_create(output, V_NT_OBJECT, MY_OBJECT);
	p_node_set_name(obj, "sphere");
	geo = p_output_node_create(output, V_NT_GEOMETRY, MY_GEOMETRY);
	p_node_set_name(geo, "sphere-geo");

	p_node_o_link_set(obj, geo, "geometry", 0);

	quad_levels = side_splits - 2;	/* Top and bottom layers are triangles. */

	/* Create outer vertices. */
	lay = p_node_g_layer_find(geo, "vertex");
	for(j = 0; j <= quad_levels; j++)
	{
		y = radius * sin(-M_PI/2 + M_PI * (j + 1) / side_splits);
		r = radius * cos(-M_PI/2 + M_PI * (j + 1) / side_splits);
		for(i = 0; i < end_splits; i++)
		{
			angle = 2 * M_PI * (i / (real64) end_splits);
			p_node_g_vertex_set_xyz(lay, j * end_splits + i, r * cos(angle), y, r * -sin(angle));
		}
	}
	bc = (quad_levels + 1) * end_splits;
	p_node_g_vertex_set_xyz(lay, bc, 0.0, -radius, 0.0);
	tc = bc + 1;
	p_node_g_vertex_set_xyz(lay, tc, 0.0, radius,  0.0);

	lay = p_node_g_layer_find(geo, "polygon");
	/* Create bottom triangles. */
	for(i = 0; i < end_splits; i++)
		POLY("bottom triangle", lay, i, i, (i + 1) % end_splits, bc, ~0u);
	/* Create intermediary quads, if any. */
	for(i = 0; i < quad_levels; i++)
	{
		pos = i * end_splits;
		for(j = 0; j < end_splits; j++)
		{
			POLY("side quad", lay, end_splits + pos + j,
							   pos + j,
							   pos + j + end_splits,
							   pos + (j + 1) % end_splits + end_splits,
							   pos + (j + 1) % end_splits);
		}
	}
	/* Create top triangles. */
	for(i = 0; i < end_splits; i++)
		POLY("top triangle", lay, (quad_levels + 1) * end_splits + i,
						   tc - 2 - end_splits + (i + 1) % end_splits,
						   tc - 2 - end_splits + i,
						   tc, ~0u);

	if(uv_map)
	{
		uint32	poly;
		real64	u[4], v[4];

		ulay = p_node_g_layer_create(geo, "map_u", VN_G_LAYER_POLYGON_CORNER_REAL, 0, 0.0f);
		vlay = p_node_g_layer_create(geo, "map_v", VN_G_LAYER_POLYGON_CORNER_REAL, 0, 0.0f);

		/* Texture-map the bottom polygons, the ones touching the "south pole". */
		for(i = poly = 0; i < end_splits; i++, poly++)
		{
			compute_quad_uv(u, v, i, 0, end_splits, side_splits);
			p_node_g_polygon_set_corner_real64(ulay, poly,
							   u[0],
							   u[1],
							   0.5, 0.0);
			p_node_g_polygon_set_corner_real64(vlay, poly,	/* V values are the same for every triangle. Flipped, though. */
							   v[1], v[1],
							   1.0, 0.0);
		}
		/* Texture map the main polygons, the ones not touching a pole vertex. */
		for(j = 0; j < quad_levels; j++)
		{
			for(i = 0; i < end_splits; i++, poly++)
			{
				compute_quad_uv(u, v, i, j + 1, end_splits, side_splits);
				p_node_g_polygon_set_corner_real64(ulay, poly, u[0], u[1], u[2], u[3]);
				p_node_g_polygon_set_corner_real64(vlay, poly, v[0], v[1], v[2], v[3]);
			}
		}
		/* Texture-map the top polygons, the ones touching the "north pole". */
		for(i = 0; i < end_splits; i++, poly++)
		{
			compute_quad_uv(u, v, i, side_splits, end_splits, side_splits);	/* Works for tris to, if you're careful. */
			p_node_g_polygon_set_corner_real64(ulay, poly, u[0], u[1], u[2], u[3]);
			p_node_g_polygon_set_corner_real64(vlay, poly, v[1], v[1], 0.0, 0.0);
		}
	}

	p_node_g_crease_set_vertex(geo, NULL, ~0u);
	p_node_g_crease_set_edge(geo, NULL, ~0u);

	return P_COMPUTE_DONE;	/* Sleep until size changes. */
}
Beispiel #8
0
/* This gets called whenever the input, the size, changes. Create a cube with the given side length. */
static PComputeStatus compute(PPInput *input, PPOutput output, void *state)
{
	enum { MY_OBJECT, MY_GEOMETRY };			/* Node labels. */
	PONode		*obj, *geo;
	real32		height = p_input_real32(input[0]);	/* Read out the size. */
	uint32		end_splits = p_input_uint32(input[1]);	/* And the top/bottom tesselation level. */
	uint32		side_splits = p_input_uint32(input[2]);	/* And the side tesselation level. */
	real64		angle, x, y;
	uint32		i, j, pos, poly, corner, bc, tc;
	uint32		v0, v1, v2, v3;
	PNGLayer	*lay;

	obj = p_output_node_create(output, V_NT_OBJECT, MY_OBJECT);
	p_node_set_name(obj, "cylinder");
	geo = p_output_node_create(output, V_NT_GEOMETRY, MY_GEOMETRY);

	p_node_o_link_set(obj, geo, "geometry", 0);

	/* Create outer vertices. */
	lay = p_node_g_layer_find(geo, "vertex");
	for(j = 0; j <= side_splits; j++)
	{
		y = j * height / side_splits;
		for(i = 0; i < end_splits; i++, pos++)
		{
			angle = 2 * M_PI * (i / (double) end_splits);
			p_node_g_vertex_set_xyz(lay, j * end_splits + i, cos(angle), y, -sin(angle));
		}
	}
	/* Create bottom center vertex. */
	bc = (side_splits + 1) * end_splits;
	p_node_g_vertex_set_xyz(lay, bc, 0.0, 0.0, 0.0);
	/* Create top center. It's at bc+1. */
	tc = bc + 1;
	p_node_g_vertex_set_xyz(lay, tc, 0.0, height, 0.0);
	/* Create bottom surface. */
	lay = p_node_g_layer_find(geo, "polygon");
	for(i = 0; i < end_splits; i++)
		POLY("bottom", lay, i, i, (i + 1) % end_splits, bc, ~0u);
	/* Create side polygons (quads). */
	for(j = 0; j < side_splits; j++)
	{
		pos = j * end_splits;
		for(i = 0; i < end_splits; i++)
		{
			POLY("side", lay, end_splits + j * end_splits + i,
			     pos + i + end_splits,
			     pos + (i + 1) % end_splits + end_splits,
			     pos + (i + 1) % end_splits,
			     pos + i);
		}
	}
	/* Create top surface. */
	pos = tc - 1 - end_splits;
	for(i = 0; i < end_splits; i++)
		POLY("top", lay, end_splits + side_splits * end_splits + i, pos + (i + 1) % end_splits, pos + i, tc, ~0u);

	p_node_g_crease_set_vertex(geo, NULL, ~0u);
	p_node_g_crease_set_edge(geo, NULL, ~0u);

	return P_COMPUTE_DONE;	/* Sleep until size changes. */
}