Tensor HeightField::operator()(math::Vector2f const & p) const { static const int dx = 2, dy = 2; if (m_image.isNull()) { return Tensor(); } QPoint ip = m_image.toImageCoords(p).toPoint(); if (! QRect(QPoint(0,0), m_image.size()-QSize(dx,dy)).contains(ip)) { return Tensor(); } QRgb pix0 = m_image.pixel(ip); float f0 = QColor::fromRgb(pix0).valueF(); QRgb pix1 = m_image.pixel(ip + QPoint(dx,0)); float f1 = QColor::fromRgb(pix1).valueF(); QRgb pix2 = m_image.pixel(ip + QPoint(0,dy)); float f2 = QColor::fromRgb(pix2).valueF(); qreal dHx = 100.0f * (f1 - f0); qreal dHy = 100.0f * (f2 - f0); qreal f = atan2f(dHy, dHx) + M_PI/2.0f; qreal r = sqrtf(pow2(dHx) + pow2(dHy)); return Tensor(r, f); }
math::Tensor BasisField::operator()(math::Vector2f const & p) const { if (0 == m_singularityType) { return scale * m_regularValue; } else { Q_ASSERT(m_singularityType < NumSingularityTypes); Vector2f v = (p - p0).normalized(); float x = v(0); float y = v(1); switch (m_singularityType) { case SingularityType_Center: return scale * math::Tensor::fromValues(pow2(y)-pow2(x), -2.0f*x*y); case SingularityType_Wedge: return scale * math::Tensor::fromValues(x, y); case SingularityType_Node: return scale * math::Tensor::fromValues(pow2(x)-pow2(y), 2.0f*x*y); case SingularityType_Trisector: return scale * math::Tensor::fromValues(x, -y); case SingularityType_Saddle: return scale * math::Tensor::fromValues(pow2(x)-pow2(y), -2.0f*x*y); case SingularityType_Focus: return scale * math::Tensor::fromValues(pow2(y)-pow2(x), 2.0f*x*y); default: // not reached, hopefully return math::Tensor(); } } }