【问题标题】:Position on Node After Rotation旋转后节点上的位置
【发布时间】:2014-09-29 07:13:19
【问题描述】:

好的,所以我有一个节点,它的 node.size 是一个 (5,5) 矩形。它的位置是(100,100),它的锚点是默认的(0.5, 0.5)。

我试图找到最右边的点,但仍然是 Y 中心。这自然返回了点 (102.5, 100)。太棒了。我通过简单地使用CGPointMake(node.position + node.size.width/2, node.position);找到了重点

这很好用,但问题是我想旋转节点,同时仍然知道那个点是什么。我想知道它们是否是我可以使用节点 zRotation 执行的某种数学运算,以便在旋转后找到新点(节点框架上的同一点)。

为了清楚起见,我想知道节点旋转后原来是 102.5、100 的点在哪里。

非常感谢大家的所有回答

【问题讨论】:

  • 非常感谢您的建议,这正是我迄今为止所做的。我将研究围绕圆/半径的旋转点,但现在我刚刚在父节点内的点处附加了一个子节点。我只是想知道它们是否比每次需要时都创建一个新节点更容易,CPU 密集型过程。再次非常感谢您。

标签: objective-c xcode sprite-kit coordinates coordinate-systems


【解决方案1】:

r 为精灵的锚点到兴趣点的距离。在你的情况下,

r = sqrt(dx*dx+dy*dy) = 2.5;

其中 dx = 2.5 和 dy = 0。

另外,设 theta 为旋转角度,初始为零。我们现在在极坐标中有了一个点 (r, theta),它表示点 (2.5, 0)。我们现在可以通过改变 theta 来围绕精灵的锚点旋转点。旋转精灵后,我们通过

将 (r, theta) 转换为笛卡尔坐标
x = r * cos(theta);
y = r * sin(theta);

并添加精灵的位置以将点转换为场景坐标。

x = x + sprite.position.x;
y = y + sprite.position.y;

编辑:我认为这就是你想要实现的。

@interface MyScene()

@property SKSpriteNode *object1;
@property SKSpriteNode *object2;

@end

@implementation MyScene

-(id)initWithSize:(CGSize)size
{
    if(self = [super initWithSize:size]) {
        _object1 = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(10,5)];
        _object1.position = CGPointMake(100, 100);
        [self addChild:_object1];
        SKAction *wait = [SKAction waitForDuration: 2.5f];
        SKAction *rotate = [SKAction rotateByAngle:3*M_PI/4 duration:2.0f];
        SKAction *addObject = [SKAction runBlock:^{
            _object2 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(10,5)];

            _object2.zRotation = _object1.zRotation;

            CGFloat dx = _object1.size.width / 2;
            CGFloat dy = 0;
            CGFloat r = sqrtf(dx*dx + dy*dy);
            CGFloat x = r*cosf(_object1.zRotation);
            CGFloat y = r*sinf(_object1.zRotation);

            _object2.position = CGPointMake(_object1.position.x + 2*x, _object1.position.y + 2*y);

            [self addChild:_object2];
        }];
        SKAction *seq = [SKAction sequence:@[wait, rotate, addObject]];
        [_object1 runAction:seq];
    }
    return self;
}

【讨论】:

  • 这太完美了,非常感谢。一开始我不明白,但是当我研究极坐标的那一刻,一切都变得非常有意义。再次非常感谢你,我认为这将完美地满足我的要求。
  • 你完全正确。主要问题是我在勾股定理方程中包含对象框架高度,而我真的应该将其设置为 0,因为我只需要知道 x 轴距对象中心的长度。再次非常感谢您,您给了我们很大的帮助。
【解决方案2】:

好的,我必须发布代码,所以我必须回答这个问题。

所以我尝试了你的方法 0x141E,效果很好。我遇到的唯一问题是,只要角度不是 0.5PI 的倍数,它似乎计算不正确。也许这只是我编码它的方式。我的代码的目标是通过测量一个对象的最左侧中间点与其他对象最右侧中间点之间的距离,将一个对象放在另一个旁边。这样他们就会接触到左侧和右侧......基本上并排。我首先放置了一个对象,然后使用您给定的算法添加了第二个对象,但是如上所述的结果在可被 0.5 PI 整除的角度之间有点奇怪。这是我所做的,如果你想看看我在说什么,如果你将代码直接导入 XCode,它应该可以工作(对不起,我没有足够的代表来附加图像,否则我会给出截图):

//This is the MyScene implementation file
@interface MyScene()
{
    SKSpriteNode *_object1;
    SKSpriteNode *_object2;
}
@end

@implementation MyScene
-(id)initWithSize:(CGSize)size
{
    if(self = [super initWithSize:size]
    {
        object1 = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(10,5)];
        [self addChild:object1];
        //The wait is just to make it feel smoother and not so sudden when starting up the simulator
        SKAction *wait = [SKAction waitForDuration: 2.5f];
        SKAction *rotate = [SKAction rotateByAngle:0.25*M_PI duration:2.0f];
        SKAction *addObject = [SKAction runBlock:^{
            _object2 = [spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(10,5)];

            //I set the rotation of the second object to the rotation of the first so they will always be touching side-by-side
            _object2.zRotation = _object1.zRotation;

            //I used the full width and heigth rather than half to save time. The two ojects are of equal width and height so instead of finding both distances and adding them together I just doubled the distance
            CGFloat r = sqrtf(_object2.frame.size.width*_object2.frame.size.width+_object2.frame.size.height*_object2.frame.size.height);
            CGFloat x = r*cosf(_object2.zRotation);
            CGFloat y = r*sinf(_object2.zRotation);

            object2.position = CGPointMake(_object2.position.x + x, _object2.position + y);

            [self addChild:_object2];
        }
        SKAction *seq = [SKAction sequence:@[wait, rotate, addObject]];
        [self runAction:seq];
    }
}
@end

再次感谢您迄今为止提供的所有帮助,并更加感谢您未来可能提供的所有帮助。

【讨论】:

    猜你喜欢
    • 2018-11-01
    • 1970-01-01
    • 2018-12-10
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多