Skip to content

Commit 351b27c

Browse files
committed
fix #119: Translate coordinates in contains() correctly
1 parent 9aa85b9 commit 351b27c

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

src/renderedtarget.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,19 +548,22 @@ const std::vector<QPoint> &RenderedTarget::hullPoints() const
548548

549549
bool RenderedTarget::contains(const QPointF &point) const
550550
{
551-
if (!m_costume || !m_texture.isValid() || !m_cpuTexture.isValid())
551+
if (!m_costume || !m_texture.isValid() || !m_cpuTexture.isValid() || !parentItem())
552552
return false;
553553

554554
if (m_stageModel)
555555
return true; // the stage contains any point within the scene
556556

557-
if (!boundingRect().contains(point))
557+
const double scaleRatio = m_skin->getTextureScale(m_texture) / m_skin->getTextureScale(m_cpuTexture);
558+
QPointF translatedPoint = mapToItem(parentItem(), point);
559+
translatedPoint = mapFromStageWithOriginPoint(translatedPoint);
560+
translatedPoint /= scaleRatio;
561+
562+
if (!boundingRect().contains(translatedPoint))
558563
return false;
559564

560565
const std::vector<QPoint> &points = hullPoints();
561-
562-
const double scaleRatio = m_skin->getTextureScale(m_texture) / m_skin->getTextureScale(m_cpuTexture);
563-
QPoint intPoint = (point / scaleRatio).toPoint();
566+
QPoint intPoint = translatedPoint.toPoint();
564567
auto it = std::lower_bound(points.begin(), points.end(), intPoint, [](const QPointF &lhs, const QPointF &rhs) { return (lhs.y() < rhs.y()) || (lhs.y() == rhs.y() && lhs.x() < rhs.x()); });
565568

566569
if (it == points.end()) {
@@ -696,6 +699,23 @@ QPointF RenderedTarget::transformPoint(double scratchX, double scratchY, double
696699
return QPointF(x, y);
697700
}
698701

702+
QPointF RenderedTarget::mapFromStageWithOriginPoint(const QPointF &scenePoint) const
703+
{
704+
// mapFromItem() doesn't use the transformOriginPoint property, so we must do this ourselves
705+
QTransform t;
706+
const double mirror = m_mirrorHorizontally ? -1 : 1;
707+
const double originX = transformOriginPoint().x();
708+
const double originY = transformOriginPoint().y();
709+
t.translate(originX, originY);
710+
t.rotate(-rotation());
711+
t.scale(1 / scale() * mirror, 1 / scale());
712+
t.translate(-originX * mirror, -originY);
713+
t.translate(-x(), -y());
714+
715+
QPointF localPoint = t.map(scenePoint);
716+
return localPoint;
717+
}
718+
699719
CpuTextureManager *RenderedTarget::textureManager()
700720
{
701721
if (!m_textureManager)

src/renderedtarget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class RenderedTarget : public IRenderedTarget
116116
bool convexHullPointsNeeded() const;
117117
void updateHullPoints();
118118
QPointF transformPoint(double scratchX, double scratchY, double originX, double originY, double rot) const;
119+
QPointF mapFromStageWithOriginPoint(const QPointF &scenePoint) const;
119120
CpuTextureManager *textureManager();
120121

121122
libscratchcpp::IEngine *m_engine = nullptr;

test/renderedtarget/renderedtarget_test.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,8 @@ TEST_F(RenderedTargetTest, HullPoints)
306306
model.init(&sprite);
307307

308308
QQuickItem parent;
309-
parent.setWidth(200);
310-
parent.setHeight(100);
309+
parent.setWidth(480);
310+
parent.setHeight(360);
311311
RenderedTarget target(&parent);
312312
target.setEngine(&engine);
313313
target.setSpriteModel(&model);
@@ -357,7 +357,23 @@ TEST_F(RenderedTargetTest, HullPoints)
357357
ASSERT_TRUE(target.contains({ 3, 3 }));
358358
ASSERT_FALSE(target.contains({ 3.3, 3.5 }));
359359

360+
// Test contains() with horizontal mirroring
361+
target.updateRotationStyle(Sprite::RotationStyle::LeftRight);
362+
target.updateDirection(-45);
363+
target.setX(25);
364+
target.setY(30);
365+
ASSERT_FALSE(target.contains({ 0, 0 }));
366+
ASSERT_TRUE(target.contains({ -1, 1 }));
367+
ASSERT_FALSE(target.contains({ -2, 2 }));
368+
ASSERT_TRUE(target.contains({ -3, 2 }));
369+
ASSERT_FALSE(target.contains({ -3.5, 2.1 }));
370+
ASSERT_TRUE(target.contains({ -2, 3 }));
371+
ASSERT_FALSE(target.contains({ -3.3, 3.5 }));
372+
360373
// Test containsScratchPoint()
374+
target.updateDirection(0);
375+
target.setX(25);
376+
target.setY(30);
361377
ASSERT_FALSE(target.containsScratchPoint(-227.5, 165)); // [0, 0]
362378
ASSERT_FALSE(target.containsScratchPoint(-226.5, 165)); // [1, 0]
363379
ASSERT_FALSE(target.containsScratchPoint(-225.5, 165)); // [2, 0]

0 commit comments

Comments
 (0)