void wxScrollHelperNative::DoAdjustScrollbar(GtkAdjustment *adj, int pixelsPerLine, int winSize, int virtSize, int *pos, int *lines, int *linesPerPage) { if ( pixelsPerLine == 0 ) { adj->upper = 1.0; adj->page_increment = 1.0; adj->page_size = 1.0; } else // we do have scrollbar { adj->upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine; adj->page_size = winSize / pixelsPerLine; adj->page_increment = winSize / pixelsPerLine; // Special case. When client and virtual size are very close but // the client is big enough, kill scrollbar. if ((adj->page_size < adj->upper) && (winSize >= virtSize)) adj->page_size += 1.0; // If the scrollbar hits the right side, move the window // right to keep it from over extending. if ( !wxIsNullDouble(adj->value) && (adj->value + adj->page_size > adj->upper) ) { adj->value = adj->upper - adj->page_size; if (adj->value < 0.0) adj->value = 0.0; if ( m_win->GetChildren().empty() ) { // This is enough without child windows *pos = (int)adj->value; } else { // We need to actually scroll window gtk_signal_emit_by_name( GTK_OBJECT(adj), "value_changed" ); } } } *lines = (int)(adj->upper + 0.5); *linesPerPage = (int)(adj->page_increment + 0.5); gtk_signal_emit_by_name( GTK_OBJECT(adj), "changed" ); }
wxDouble wxPoint2DDouble::GetVectorAngle() const { if ( wxIsNullDouble(m_x) ) { if ( m_y >= 0 ) return 90; else return 270; } if ( wxIsNullDouble(m_y) ) { if ( m_x >= 0 ) return 0; else return 180; } wxDouble deg = atan2( m_y , m_x ) * 180 / M_PI; if ( deg < 0 ) { deg += 360; } return deg; }
// Example of use: // wxTransformMatrix mat = dc.GetTransformation(); // mat.Invert(); // mat.InverseTransformPoint(x, y, x1, y1); // OR (shorthand:) // dc.LogicalToDevice(x, y, x1, y1); // The latter is slightly less efficient if we're doing several // conversions, since the matrix is inverted several times. bool wxTransformMatrix::InverseTransformPoint(double x, double y, double& tx, double& ty) const { if (IsIdentity()) { tx = x; ty = y; return true; } const double z = (1.0 - m_matrix[0][2] * x - m_matrix[1][2] * y) / m_matrix[2][2]; if ( wxIsNullDouble(z) ) return false; tx = x * m_matrix[0][0] + y * m_matrix[1][0] + z * m_matrix[2][0]; ty = x * m_matrix[0][1] + y * m_matrix[1][1] + z * m_matrix[2][1]; return true; }
// Invert matrix bool wxTransformMatrix::Invert(void) { double inverseMatrix[3][3]; // calculate the adjoint inverseMatrix[0][0] = wxCalculateDet(m_matrix[1][1],m_matrix[2][1],m_matrix[1][2],m_matrix[2][2]); inverseMatrix[0][1] = -wxCalculateDet(m_matrix[0][1],m_matrix[2][1],m_matrix[0][2],m_matrix[2][2]); inverseMatrix[0][2] = wxCalculateDet(m_matrix[0][1],m_matrix[1][1],m_matrix[0][2],m_matrix[1][2]); inverseMatrix[1][0] = -wxCalculateDet(m_matrix[1][0],m_matrix[2][0],m_matrix[1][2],m_matrix[2][2]); inverseMatrix[1][1] = wxCalculateDet(m_matrix[0][0],m_matrix[2][0],m_matrix[0][2],m_matrix[2][2]); inverseMatrix[1][2] = -wxCalculateDet(m_matrix[0][0],m_matrix[1][0],m_matrix[0][2],m_matrix[1][2]); inverseMatrix[2][0] = wxCalculateDet(m_matrix[1][0],m_matrix[2][0],m_matrix[1][1],m_matrix[2][1]); inverseMatrix[2][1] = -wxCalculateDet(m_matrix[0][0],m_matrix[2][0],m_matrix[0][1],m_matrix[2][1]); inverseMatrix[2][2] = wxCalculateDet(m_matrix[0][0],m_matrix[1][0],m_matrix[0][1],m_matrix[1][1]); // now divide by the determinant double det = m_matrix[0][0] * inverseMatrix[0][0] + m_matrix[0][1] * inverseMatrix[1][0] + m_matrix[0][2] * inverseMatrix[2][0]; if ( wxIsNullDouble(det) ) return false; inverseMatrix[0][0] /= det; inverseMatrix[1][0] /= det; inverseMatrix[2][0] /= det; inverseMatrix[0][1] /= det; inverseMatrix[1][1] /= det; inverseMatrix[2][1] /= det; inverseMatrix[0][2] /= det; inverseMatrix[1][2] /= det; inverseMatrix[2][2] /= det; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { m_matrix[i][j] = inverseMatrix[i][j]; } } m_isIdentity = IsIdentity1(); return true; }
// counter clockwise rotate around a point // // cos(r) -sin(r) x(1-cos(r))+y(sin(r) // sin(r) cos(r) y(1-cos(r))-x(sin(r) // 0 0 1 wxTransformMatrix& wxTransformMatrix::Rotate(const double °rees, const double &x, const double &y) { double angle = degrees * pi / 180.0; double c = cos(angle); double s = sin(angle); double r00,r10,r20,r01,r11,r21; if (m_isIdentity) { double tx = x*(1-c)+y*s; double ty = y*(1-c)-x*s; r00 = c ; r10 = -s; r20 = tx; r01 = s; r11 = c; r21 = ty; } else if ( !wxIsNullDouble(x) || !wxIsNullDouble(y) ) { double tx = x*(1-c)+y*s; double ty = y*(1-c)-x*s; r00 = c * m_matrix[0][0] - s * m_matrix[0][1] + tx * m_matrix[0][2]; r10 = c * m_matrix[1][0] - s * m_matrix[1][1] + tx * m_matrix[1][2]; r20 = c * m_matrix[2][0] - s * m_matrix[2][1] + tx;// * m_matrix[2][2]; r01 = c * m_matrix[0][1] + s * m_matrix[0][0] + ty * m_matrix[0][2]; r11 = c * m_matrix[1][1] + s * m_matrix[1][0] + ty * m_matrix[1][2]; r21 = c * m_matrix[2][1] + s * m_matrix[2][0] + ty;// * m_matrix[2][2]; } else { r00 = c * m_matrix[0][0] - s * m_matrix[0][1]; r10 = c * m_matrix[1][0] - s * m_matrix[1][1]; r20 = c * m_matrix[2][0] - s * m_matrix[2][1]; r01 = c * m_matrix[0][1] + s * m_matrix[0][0]; r11 = c * m_matrix[1][1] + s * m_matrix[1][0]; r21 = c * m_matrix[2][1] + s * m_matrix[2][0]; } m_matrix[0][0] = r00; m_matrix[1][0] = r10; m_matrix[2][0] = r20; m_matrix[0][1] = r01; m_matrix[1][1] = r11; m_matrix[2][1] = r21; /* or like this wxTransformMatrix rotate; rotate.m_matrix[2][0] = tx; rotate.m_matrix[2][1] = ty; rotate.m_matrix[0][0] = c; rotate.m_matrix[0][1] = s; rotate.m_matrix[1][0] = -s; rotate.m_matrix[1][1] = c; rotate.m_isIdentity=false; *this = rotate * (*this); */ m_isIdentity = IsIdentity1(); return *this; }
// scale a matrix in 2D // // xs 0 xc(1-xs) // 0 ys yc(1-ys) // 0 0 1 // wxTransformMatrix& wxTransformMatrix::Scale(const double &xs, const double &ys,const double &xc, const double &yc) { double r00,r10,r20,r01,r11,r21; if (m_isIdentity) { double tx = xc*(1-xs); double ty = yc*(1-ys); r00 = xs; r10 = 0; r20 = tx; r01 = 0; r11 = ys; r21 = ty; } else if ( !wxIsNullDouble(xc) || !wxIsNullDouble(yc) ) { double tx = xc*(1-xs); double ty = yc*(1-ys); r00 = xs * m_matrix[0][0]; r10 = xs * m_matrix[1][0]; r20 = xs * m_matrix[2][0] + tx; r01 = ys * m_matrix[0][1]; r11 = ys * m_matrix[1][1]; r21 = ys * m_matrix[2][1] + ty; } else { r00 = xs * m_matrix[0][0]; r10 = xs * m_matrix[1][0]; r20 = xs * m_matrix[2][0]; r01 = ys * m_matrix[0][1]; r11 = ys * m_matrix[1][1]; r21 = ys * m_matrix[2][1]; } m_matrix[0][0] = r00; m_matrix[1][0] = r10; m_matrix[2][0] = r20; m_matrix[0][1] = r01; m_matrix[1][1] = r11; m_matrix[2][1] = r21; /* or like this // first translate to origin O (*this).Translate(-x_cen, -y_cen); // now do the scaling wxTransformMatrix scale; scale.m_matrix[0][0] = x_fac; scale.m_matrix[1][1] = y_fac; scale.m_isIdentity = IsIdentity1(); *this = scale * (*this); // translate back from origin to x_cen, y_cen (*this).Translate(x_cen, y_cen); */ m_isIdentity = IsIdentity1(); return *this; }