bool ON_BezierCage::SetCV( int i, int j, int k, ON::point_style style, const double* Point )
{
  bool rc = true;
  int n;
  double w;

  double* cv = CV(i,j,k);
  if ( !cv )
    return false;

  switch ( style ) {

  case ON::not_rational:  // input Point is not rational
    memcpy( cv, Point, m_dim*sizeof(*cv) );
    if ( IsRational() ) {
      // NURBS surface is rational - set weight to one
      cv[m_dim] = 1.0;
    }
    break;

  case ON::homogeneous_rational:  // input Point is homogeneous rational
    if ( IsRational() ) {
      // NURBS surface is rational
      memcpy( cv, Point, (m_dim+1)*sizeof(*cv) );
    }
    else {
      // NURBS surface is not rational
      w = (Point[m_dim] != 0.0) ? 1.0/Point[m_dim] : 1.0;
      for ( n = 0; n < m_dim; n++ ) {
        cv[n] = w*Point[n];
      }
    }
    break;

  case ON::euclidean_rational:  // input Point is euclidean rational
    if ( IsRational() ) {
      // NURBS surface is rational - convert euclean point to homogeneous form
      w = Point[m_dim];
      for ( n = 0; n < m_dim; n++ )
        cv[i] = w*Point[i];
      cv[m_dim] = w;
    }
    else {
      // NURBS surface is not rational
      memcpy( cv, Point, m_dim*sizeof(*cv) );
    }
    break;

  case ON::intrinsic_point_style:
    n = m_is_rat?m_dim+1:m_dim;
    memcpy(cv,Point,n*sizeof(*cv));
    break;
    
  default:
    rc = false;
    break;
  }
  return rc;
}
bool ON_BezierCage::MakeRational()
{
  if ( !IsRational() ) 
  {
    ON_ERROR("TODO: fill in ON_BezierCage::MakeRational()");
    /*
    const int dim = Dimension();
    if ( m_order[0] > 0 && m_order[1] > 0 && m_order[2] > 0 && dim > 0 ) {
      const double* old_cv;
      double* new_cv;
      int cvi, cvj, j, cvstride;
      if ( m_cv_stride[0] < m_cv_stride[1] ) {
        cvstride = m_cv_stride[0] > dim ? m_cv_stride[0] : dim+1;
        ReserveCVCapacity( cvstride*m_order[0]*m_order[1] );
        new_cv = m_cv + cvstride*m_order[0]*m_order[1]-1;
				for ( cvj = m_order[1]-1; cvj >= 0; cvj-- ) {
          for ( cvi = m_order[0]-1; cvi >= 0; cvi-- ) {
            old_cv = CV(cvi,cvj)+dim-1;
            *new_cv-- = 1.0;
            for ( j = 0; j < dim; j++ ) {
              *new_cv-- = *old_cv--;
            }
          }
        }
        m_cv_stride[0] = dim+1;
        m_cv_stride[1] = (dim+1)*m_order[0];
      }
      else {
        cvstride = m_cv_stride[1] > dim ? m_cv_stride[1] : dim+1;
        ReserveCVCapacity( cvstride*m_order[0]*m_order[1] );
        new_cv = m_cv + cvstride*m_order[0]*m_order[1]-1;
        for ( cvi = m_order[0]-1; cvi >= 0; cvi-- ) {
          for ( cvj = m_order[1]-1; cvj >= 0; cvj-- ) {
            old_cv = CV(cvi,cvj)+dim-1;
            *new_cv-- = 1.0;
            for ( j = 0; j < dim; j++ ) {
              *new_cv-- = *old_cv--;
            }
          }
        }
        m_cv_stride[1] = dim+1;
        m_cv_stride[0] = (dim+1)*m_order[1];
      }
      m_is_rat = 1;
    }
    */
  }
  return IsRational();
}
bool ON_BezierCage::GetCV( int i, int j, int k, ON::point_style style, double* Point ) const
{
  const double* cv = CV(i,j,k);
  if ( !cv )
    return false;
  int dim = Dimension();
  double w = ( IsRational() ) ? cv[dim] : 1.0;
  switch(style) {
  case ON::euclidean_rational:
    Point[dim] = w;
    // no break here
  case ON::not_rational:
    if ( w == 0.0 )
      return false;
    w = 1.0/w;
    while(dim--) *Point++ = *cv++ * w;
    break;
  case ON::homogeneous_rational:
    Point[dim] = w;
    memcpy( Point, cv, dim*sizeof(*Point) );
    break;
  default:
    return false;
  }
  return true;
}
bool ON_BezierCage::MakeNonRational()
{
  if ( IsRational() ) 
  {
    ON_ERROR("TODO: fill in ON_BezierCage::MakeNonRational()");
    /*
    const int dim = Dimension();
    if ( m_order[0] > 0 && m_order[1] > 0 && dim > 0 ) {
      double w;
      const double* old_cv;
      double* new_cv = m_cv;
      int cvi, cvj, j;
      if ( m_cv_stride[0] < m_cv_stride[1] ) {
        for ( cvj = 0; cvj < m_order[1]; cvj++ ) {
          for ( cvi = 0; cvi < m_order[0]; cvi++ ) {
            old_cv = CV(cvi,cvj);
            w = old_cv[dim];
            w = ( w != 0.0 ) ? 1.0/w : 1.0;
            for ( j = 0; j < dim; j++ ) {
              *new_cv++ = w*(*old_cv++);
            }
          }
        }
        m_cv_stride[0] = dim;
        m_cv_stride[1] = dim*m_order[0];
      }
      else {
        for ( cvi = 0; cvi < m_order[0]; cvi++ ) {
          for ( cvj = 0; cvj < m_order[1]; cvj++ ) {
            old_cv = CV(cvi,cvj);
            w = old_cv[dim];
            w = ( w != 0.0 ) ? 1.0/w : 1.0;
            for ( j = 0; j < dim; j++ ) {
              *new_cv++ = w*(*old_cv++);
            }
          }
        }
        m_cv_stride[1] = dim;
        m_cv_stride[0] = dim*m_order[1];
      }
      m_is_rat = 0;
    }
    */
  }
  return ( !IsRational() ) ? true : false;
}
Пример #5
0
  std::vector<RingElem> BM_QQ(const SparsePolyRing& P, const ConstMatrixView& pts_in)
  {
    const long NumPts = NumRows(pts_in);
    const long dim = NumCols(pts_in);
    matrix pts = NewDenseMat(RingQQ(), NumPts, dim);
    for (long i=0; i < NumPts; ++i)
      for (long j=0; j < dim; ++j)
      {
        BigRat q;
        if (!IsRational(q, pts_in(i,j))) throw 999;
        SetEntry(pts,i,j, q);
      }

    // Ensure input pts have integer coords by using
    // scale factors for each indet.
    vector<BigInt> ScaleFactor(dim, BigInt(1));
    for (long j=0; j < dim; ++j)
      for (long i=0; i < NumPts; ++i)
        ScaleFactor[j] = lcm(ScaleFactor[j], ConvertTo<BigInt>(den(pts(i,j))));

    mpz_t **points = (mpz_t**)malloc(NumPts*sizeof(mpz_t*));
    for (long i=0; i < NumPts; ++i)
    {
      points[i] = (mpz_t*)malloc(dim*sizeof(mpz_t));
      for (long j=0; j < dim; ++j) mpz_init(points[i][j]);
      for (long j=0; j < dim; ++j)
      {
        mpz_set(points[i][j], mpzref(ConvertTo<BigInt>(ScaleFactor[j]*pts(i,j))));
      }
    }


    BMGB char0; // these will be "filled in" by BM_affine below
    BM modp;    //
            
    pp_cmp_PPM = &PPM(P); // not threadsafe!
    BM_affine(&char0, &modp, dim, NumPts, points, pp_cmp); // THIS CALL DOES THE REAL WORK!!!
    pp_cmp_PPM = NULL;
    for (long i=NumPts-1; i >=0 ; --i)
    {
      for (long j=0; j < dim; ++j) mpz_clear(points[i][j]);
      free(points[i]);
    }
    free(points);

    if (modp == NULL) { if (char0 != NULL) BMGB_dtor(char0); CoCoA_ERROR("Something went wrong", "BM_QQ"); }

    // Now extract the answer...
    const int GBsize = char0->GBsize;
    std::vector<RingElem> GB(GBsize);
    const long NumVars = dim;
    vector<long> expv(NumVars); // buffer for creating monomials
    for (int i=0; i < GBsize; ++i)
    {
      BigInt denom(1); // scale factor needed to make GB elem monic.
      for (int var = 0; var < NumVars; ++var)
      {
        expv[var] = modp->pp[modp->GB[i]][var];
        denom *= power(ScaleFactor[var], expv[var]);
      }
      RingElem GBelem = monomial(P, 1, expv);

      for (int j=0; j < NumPts; ++j)
      {
        if (mpq_sgn(char0->GB[i][j])==0) continue;
        BigRat c(char0->GB[i][j]);
        for (int var = 0; var < NumVars; ++var)
        {
          expv[var] = modp->pp[modp->sep[j]][var];
          c *= power(ScaleFactor[var], expv[var]);
        }
        GBelem += monomial(P, c/denom, expv);
      }
      GB[i] = GBelem;
    }
    BMGB_dtor(char0);
    BM_dtor(modp);
    return GB;
    // ignoring separators for the moment
  }
Пример #6
0
	bool isRationalObject() const { return IsRational( this->ref ); }