Commit 91caa85c authored by Paul Asmuth's avatar Paul Asmuth
Browse files

add the box_rotate_bounds convenience method

parent a8be8d1f
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
 */
#include <algorithm>
#include <iostream>
#include <math.h>
#include "layout.h"

namespace fviz {
@@ -70,5 +71,37 @@ Point layout_align(
  return layout_align(bbox, target);
}

Rectangle box_rotate_bounds(
    const Rectangle& b,
    double angle_deg) {
  auto i = sin(-angle_deg * M_PI / 180);
  auto q = cos(-angle_deg * M_PI / 180);

  auto xrange = std::minmax({
    q * (b.w * 0.5)  - i * (b.h * 0.5),
    q * (b.w * 0.5)  - i * (b.h * -0.5),
    q * (b.w * -0.5) - i * (b.h * -0.5),
    q * (b.w * -0.5) - i * (b.h * 0.5),
  });

  auto yrange = std::minmax({
    q * (b.h * 0.5)  + i * (b.w * 0.5),
    q * (b.h * -0.5) + i * (b.w * 0.5),
    q * (b.h * -0.5) + i * (b.w * -0.5),
    q * (b.h * 0.5)  + i * (b.w * -0.5),
  });

  auto rw = xrange.second - xrange.first;
  auto rh = yrange.second - yrange.first;

  Rectangle bbox_rot;
  bbox_rot.x = (b.x + b.w * 0.5) - rw * 0.5;
  bbox_rot.y = (b.y + b.h * 0.5) - rh * 0.5;
  bbox_rot.w = rw;
  bbox_rot.h = rh;

  return bbox_rot;
}

} // namespace fviz
+8 −0
Original line number Diff line number Diff line
@@ -58,5 +58,13 @@ Point layout_align(
    VAlign valign);


/**
 * Return the smallest bounding box that can contain the input box after it
 * was rotated `angle_deg` around it's center point
 */
Rectangle box_rotate_bounds(
    const Rectangle& bbox,
    double angle_deg);

} // namespace fviz
+57 −0
Original line number Diff line number Diff line
/**
 * This file is part of the "fviz" project
 *   Copyright (c) 2018 Paul Asmuth
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "graphics/brush.h"
#include "graphics/color.h"
#include "graphics/layer.h"
#include "graphics/layer_svg.h"
#include "graphics/text.h"
#include "environment.h"
#include "utils/fileutil.h"
#include "unittest.h"

using namespace fviz;

void test_box_rotate_bounds() {
  {
    Rectangle ri(0, 0, 1, 3);
    Rectangle ro = box_rotate_bounds(ri, 90);
    EXPECT_FEQ(ro.w, 3);
    EXPECT_FEQ(ro.h, 1);
    EXPECT_FEQ(ro.x, -1);
    EXPECT_FEQ(ro.y, 1);
  }

  {
    Rectangle ri(0, 0, 1, 3);
    Rectangle ro = box_rotate_bounds(ri, 180);
    EXPECT_FEQ(ro.w, 1);
    EXPECT_FEQ(ro.h, 3);
    EXPECT_FEQ(ro.x, 0);
    EXPECT_FEQ(ro.y, 0);
  }

  {
    Rectangle ri(10, 20, 1, 3);
    Rectangle ro = box_rotate_bounds(ri, 90);
    EXPECT_FEQ(ro.w, 3);
    EXPECT_FEQ(ro.h, 1);
    EXPECT_FEQ(ro.x, 9);
    EXPECT_FEQ(ro.y, 21);
  }
}

int main(int argc, char** argv) {
  test_box_rotate_bounds();
}
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@

#include "return_code.h"

const double EPSILON = 0.0001;

#define EXPECT(X) \
    if (!(X)) { \
      std::cerr << "ERROR: expectation failed: " << #X << " on line " << __LINE__ <<  std::endl; \
@@ -29,6 +31,8 @@

#define EXPECT_EQ(A, B) EXPECT((A) == (B))

#define EXPECT_FEQ(A, B) EXPECT(std::abs((A) - (B)) < EPSILON)

#define EXPECT_STREQ(A, B) EXPECT(std::string(A) == std::string(B))

#define EXPECT_OK(X) \