Commit 9edf0ca5 authored by twanvl's avatar twanvl

Allow rotations when checking bounds of symbol parts.

This will be needed to determine the correct symbol size when there are symmetries.
parent 65b02802
......@@ -7,6 +7,7 @@
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/rotation.hpp>
#include <data/symbol.hpp>
#include <script/to_value.hpp>
#include <gfx/bezier.hpp>
......@@ -184,8 +185,9 @@ void SymbolShape::enforceConstraints() {
void SymbolShape::calculateBounds() {
min_pos = Vector2D::infinity();
max_pos = -Vector2D::infinity();
Rotation rot(0);
for (int i = 0 ; i < (int)points.size() ; ++i) {
segment_bounds(*getPoint(i), *getPoint(i + 1), min_pos, max_pos);
segment_bounds(rot, *getPoint(i), *getPoint(i + 1), min_pos, max_pos);
}
}
......
......@@ -7,6 +7,7 @@
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/rotation.hpp>
#include <gfx/bezier.hpp>
#include <gfx/polynomial.hpp>
......@@ -93,20 +94,20 @@ void segment_subdivide(const ControlPoint& p0, const ControlPoint& p1, const Vec
// ----------------------------------------------------------------------------- : Bounds
void segment_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max) {
void segment_bounds(const Rotation& rot, const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max) {
assert(p1.segment_after == p2.segment_before);
if (p1.segment_after == SEGMENT_LINE) {
line_bounds (p1.pos, p2.pos, min, max);
line_bounds (rot, p1.pos, p2.pos, min, max);
} else {
bezier_bounds(p1, p2, min, max);
bezier_bounds(rot, p1, p2, min, max);
}
}
void bezier_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max) {
void bezier_bounds(const Rotation& rot, const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max) {
assert(p1.segment_after == SEGMENT_CURVE);
// First of all, the corners should be in the bounding box
point_bounds(p1.pos, min, max);
point_bounds(p2.pos, min, max);
point_bounds(rot, p1.pos, min, max);
point_bounds(rot, p2.pos, min, max);
// Solve the derivative of the bezier curve to find its extremes
// It's only a quadtratic equation :)
BezierCurve curve(p1,p2);
......@@ -118,19 +119,20 @@ void bezier_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min
for (UInt i = 0 ; i < count ; ++i) {
double t = roots[i];
if (t >=0 && t <= 1) {
point_bounds(curve.pointAt(t), min, max);
point_bounds(rot, curve.pointAt(t), min, max);
}
}
}
void line_bounds(const Vector2D& p1, const Vector2D& p2, Vector2D& min, Vector2D& max) {
point_bounds(p1, min, max);
point_bounds(p2, min, max);
void line_bounds(const Rotation& rot, const Vector2D& p1, const Vector2D& p2, Vector2D& min, Vector2D& max) {
point_bounds(rot, p1, min, max);
point_bounds(rot, p2, min, max);
}
void point_bounds(const Vector2D& p, Vector2D& min, Vector2D& max) {
min = piecewise_min(min, p);
max = piecewise_max(max, p);
void point_bounds(const Rotation& rot, const Vector2D& p, Vector2D& min, Vector2D& max) {
Vector2D pr = rot.tr(p);
min = piecewise_min(min, pr);
max = piecewise_max(max, pr);
}
// Is a point inside the bounds <min...max>?
......
......@@ -18,6 +18,8 @@
#include <util/vector2d.hpp>
#include <data/symbol.hpp>
class Rotation;
// ----------------------------------------------------------------------------- : Evaluation
/// A bezier curve for evaluation
......@@ -76,25 +78,25 @@ void segment_subdivide(const ControlPoint& p0, const ControlPoint& p1, const Vec
* min is only changed if the minimum is smaller then the current value in min,
* max only if the maximum is larger.
*/
void segment_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max);
void segment_bounds(const Rotation& rot, const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max);
/// Find a bounding box that fits a curve between p1 and p2, stores the results in min and max.
/** min is only changed if the minimum is smaller then the current value in min,
* max only if the maximum is larger
*/
void bezier_bounds(const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max);
void bezier_bounds(const Rotation& rot, const ControlPoint& p1, const ControlPoint& p2, Vector2D& min, Vector2D& max);
/// Find a bounding box that fits around p1 and p2, stores the result in min and max
/** min is only changed if the minimum is smaller then the current value in min,
* max only if the maximum is larger
*/
void line_bounds(const Vector2D& p1, const Vector2D& p2, Vector2D& min, Vector2D& max);
void line_bounds(const Rotation& rot, const Vector2D& p1, const Vector2D& p2, Vector2D& min, Vector2D& max);
/// Find a bounding 'box' that fits around a single point
/** min is only changed if the minimum is smaller then the current value in min,
* max only if the maximum is larger
*/
void point_bounds(const Vector2D& p, Vector2D& min, Vector2D& max);
void point_bounds(const Rotation& rot, const Vector2D& p, Vector2D& min, Vector2D& max);
// ----------------------------------------------------------------------------- : Point tests
......
......@@ -30,7 +30,7 @@ RandomPackPanel::RandomPackPanel(Window* parent, int id)
wxSizer* s5 = new wxStaticBoxSizer(wxHORIZONTAL, this, _LABEL_("pack totals"));
s3->Add(s5, 1, wxEXPAND | wxLEFT, 8);
s3->Add(generate, 0, wxALIGN_BOTTOM | wxLEFT, 8);
s2->Add(s3, 0, wxEXPAND | wxALL, 4);
s2->Add(s3, 0, wxEXPAND | wxALL & ~wxTOP, 4);
s2->Add(card_list, 1, wxEXPAND);
s->Add(s2, 1, wxEXPAND, 8);
s->SetSizeHints(this);
......@@ -60,6 +60,12 @@ void RandomPackPanel::onCommand(int id) {
// ?
}
// ----------------------------------------------------------------------------- : Generating
void RandomPackPanel::generate() {
//set->game->pack_types[0].generate()
}
// ----------------------------------------------------------------------------- : Clipboard
bool RandomPackPanel::canCopy() const { return card_list->canCopy(); }
......
......@@ -39,6 +39,9 @@ class RandomPackPanel : public SetWindowPanel {
private:
CardViewer* preview; ///< Card preview
FilteredCardList* card_list; ///< The list of cards
/// Generate the cards
void generate();
};
// ----------------------------------------------------------------------------- : EOF
......
......@@ -404,6 +404,7 @@ void SetWindow::onUpdateUI(wxUpdateUIEvent& ev) {
case ID_EDIT_REPLACE : ev.Enable(current_panel->canReplace());break;
// windows
case ID_WINDOW_KEYWORDS: ev.Enable(set->game->has_keywords); break;
case ID_WINDOW_RANDOM_PACK: ev.Enable(!set->game->pack_types.empty()); break;
// help
case ID_HELP_INDEX : ev.Enable(false); break; // not implemented
// other
......
......@@ -33,7 +33,7 @@ class Rotation {
/** with the given rectangle of external coordinates and a given rotation angle and zoom factor.
* if is_internal then the rect gives the internal coordinates, its origin should be (0,0)
*/
Rotation(int angle, const RealRect& rect, double zoom = 1.0, double strectch = 1.0, RotationFlags flags = ROTATION_NORMAL);
Rotation(int angle, const RealRect& rect = RealRect(0,0,0,0), double zoom = 1.0, double strectch = 1.0, RotationFlags flags = ROTATION_NORMAL);
/// Change the zoom factor
inline void setZoom(double z) { zoomX = zoomY = z; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment