Skip to content

Commit

Permalink
allow drawing on marked radius
Browse files Browse the repository at this point in the history
  • Loading branch information
rolandlo committed Nov 26, 2022
1 parent 515b49e commit cda7287
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 7 deletions.
50 changes: 47 additions & 3 deletions src/core/control/CompassController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ auto CompassController::isInsideGeometryTool(double x, double y, double border)
return std::hypot(p.x, p.y) <= geometryTool->getHeight() + border;
}

auto CompassController::getPointForPos(double a) const -> utl::Point<double> {
auto CompassController::getPointForAngle(double a) const -> utl::Point<double> {
cairo_matrix_t matrix = geometryTool->getMatrix();
double x = geometryTool->getHeight() * std::cos(a);
double y = geometryTool->getHeight() * std::sin(a);
Expand All @@ -35,12 +35,21 @@ auto CompassController::getPointForPos(double a) const -> utl::Point<double> {
return utl::Point<double>(x, y);
}

auto CompassController::getPointForRadius(double r) const -> utl::Point<double> {
cairo_matrix_t matrix = geometryTool->getMatrix();
double x = r;
double y = 0.;
cairo_matrix_transform_point(&matrix, &x, &y);

return utl::Point<double>(x, y);
}

void CompassController::createStroke(double a) {
if (!std::isnan(a)) {
angleMax = a;
angleMin = a;

const auto p = this->getPointForPos(a);
const auto p = this->getPointForAngle(a);
initializeStroke();
stroke->addPoint(Point(p.x, p.y));
stroke->addPoint(Point(p.x, p.y)); // doubled point
Expand All @@ -50,6 +59,21 @@ void CompassController::createStroke(double a) {
}
}

void CompassController::createRadius(double x) {
if (!std::isnan(x)) {
radiusMax = x;
radiusMin = x;

const auto p = posRelToSide(x, 0.);
initializeStroke();
stroke->addPoint(Point(p.x, p.y));
stroke->addPoint(Point(p.x, p.y)); // doubled point
geometryTool->notify();
} else {
g_warning("No valid radius from compass!");
}
}

void CompassController::updateStroke(double x) {
angleMax = std::max(this->angleMax, x);
angleMin = std::min(this->angleMin, x);
Expand All @@ -62,7 +86,7 @@ void CompassController::updateStroke(double x) {
stroke->addPoint(Point(c.x, c.y));
}
for (auto i = 0; i <= 100; i++) {
auto p = getPointForPos(angleMin + static_cast<double>(i) / 100.0 * (angleMax - angleMin));
auto p = getPointForAngle(angleMin + static_cast<double>(i) / 100.0 * (angleMax - angleMin));
stroke->addPoint(Point(p.x, p.y));
}
if (filled && angleMax < angleMin + 2 * M_PI) {
Expand All @@ -71,10 +95,30 @@ void CompassController::updateStroke(double x) {
geometryTool->notify();
}

void CompassController::updateRadius(double x) {
radiusMax = std::max(this->radiusMax, x);
radiusMin = std::min(this->radiusMin, x);
stroke->deletePointsFrom(0);
const auto p1 = getPointForRadius(radiusMin);
const auto p2 = getPointForRadius(radiusMax);

stroke->addPoint(Point(p1.x, p1.y));
stroke->addPoint(Point(p2.x, p2.y));
geometryTool->notify();
}

void CompassController::finalizeStroke() {
angleMax = NAN;
angleMin = NAN;
addStrokeToLayer();
}

void CompassController::finalizeRadius() {
radiusMax = NAN;
radiusMin = NAN;
addStrokeToLayer();
}

auto CompassController::existsStroke() -> bool { return !std::isnan(angleMax) && !std::isnan(angleMin); }

auto CompassController::existsRadius() -> bool { return !std::isnan(radiusMax) && !std::isnan(radiusMin); }
43 changes: 41 additions & 2 deletions src/core/control/CompassController.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,17 @@ class CompassController: public GeometryToolController {
bool isInsideGeometryTool(double x, double y, double border = 0.0) const override;

/**
* @brief the point (in document coordinates) for a given angle on the outline of the setsquare
* @brief the point (in document coordinates) for a given angle on the outline of the compass
* @param a the angle with respect to the distinguished compass axis of the point
*/
utl::Point<double> getPointForPos(double a) const;
utl::Point<double> getPointForAngle(double a) const;

/**
* @brief the point (in document coordinates) for a given radius on the marked radius of the compass
* @param r the x-coordinate with respect to a coordinate system, in which the positive x-axis
* coincides with the marked radius and the origin lies in the center of the compass
*/
utl::Point<double> getPointForRadius(double r) const;

/**
* @brief creates a stroke starting at the given angle of the outline of the compass
Expand All @@ -81,12 +88,44 @@ class CompassController: public GeometryToolController {
*/
void finalizeStroke();

/**
* @brief finishes the stroke aligned to the marked radius of the compass
*/
void finalizeRadius();

/**
* @brief creates a stroke starting at the given point of the marked radius of the compass
* @param x the x-coordinate with respect to the marked radius
*/
void createRadius(double x);

/**
* @brief updates the stroke near the marked radius of the compass
* @param x the x-coordinate with respect to the marked radius
*/
void updateRadius(double x);


/**
* checks whether a stroke already exists
*/
bool existsStroke();

/**
* checks whether a radius already exists
*/
bool existsRadius();

private:
/**
* @brief when a stroke near the radius with the measuring marks
* is drawn, the minimal and maximal radii are saved in
* the variables radiusMax and radiusMin
*
*/
double radiusMax = NAN;
double radiusMin = NAN;

/**
* @brief when a stroke near the outline of the compass is drawn, the minimal and maximal
* angles of the point to be drawn (with respect to an unrotated, and untranslated coordinate system)
Expand Down
14 changes: 12 additions & 2 deletions src/core/gui/inputdevices/CompassInputHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ CompassInputHandler::~CompassInputHandler() noexcept { this->unregisterFromPool(
auto CompassInputHandler::handlePointer(InputEvent const& event) -> bool {
const auto coords = getCoords(event);
CompassController* compassController = static_cast<CompassController*>(controller);
const auto p = compassController->posRelToSide(coords.x, coords.y);

const auto toolHandler = xournal->getControl()->getToolHandler();
switch (toolHandler->getToolType()) {
Expand All @@ -30,21 +31,27 @@ auto CompassInputHandler::handlePointer(InputEvent const& event) -> bool {
if (controller->isInsideGeometryTool(coords.x, coords.y, 0) &&
!controller->isInsideGeometryTool(coords.x, coords.y, -0.5)) {
// initialize range
const auto p = compassController->posRelToSide(coords.x, coords.y);
lastProj = std::atan2(-p.y, p.x);
compassController->createStroke(lastProj);
return true;
} else if (controller->isInsideGeometryTool(coords.x, coords.y, 0.) &&
std::abs(compassController->posRelToSide(coords.x, coords.y).y) <= 0.5 &&
std::abs(compassController->posRelToSide(coords.x, coords.y).x - 0.5 * height) <=
0.5 * height) {
compassController->createRadius(std::hypot(p.x, p.y));
return true;
}
return false;
} else if (event.type == MOTION_EVENT) {
// update range and paint
if (compassController->existsStroke()) {
const auto p = compassController->posRelToSide(coords.x, coords.y);
auto proj = std::atan2(-p.y, p.x);
proj = lastProj + std::remainder(proj - lastProj, 2 * M_PI);
compassController->updateStroke(proj);
lastProj = proj;
return true;
} else if (compassController->existsRadius()) {
compassController->updateRadius(std::hypot(p.x, p.y));
}
return false;
} else if (event.type == BUTTON_RELEASE_EVENT) {
Expand All @@ -53,6 +60,9 @@ auto CompassInputHandler::handlePointer(InputEvent const& event) -> bool {
compassController->finalizeStroke();
lastProj = NAN;
return true;
} else if (compassController->existsRadius()) {
compassController->finalizeRadius();
return true;
}
}
return false;
Expand Down

0 comments on commit cda7287

Please sign in to comment.