【问题标题】:Php code fails to give corrent result most likely logic errorPHP代码未能给出正确的结果最有可能的逻辑错误
【发布时间】:2013-04-22 12:21:15
【问题描述】:

在过去的几天里,我一直在为这个问题绞尽脑汁,而且我这辈子似乎都能找到问题代码。本质上,此代码生成具有 x 和 y 坐标和半径的随机数量的对象,然后代码检查新对象是否与任何其他对象发生碰撞,如果没有,则将其添加到主数组中然后返回调用函数。我的问题是,当我加载页面时,所有对象都在那里,但有些对象仍然相互碰撞,我不知道为什么。任何人都可以看到这个问题吗?

public function Generate($chunkX, $chunkY) {
    if (!(isset($this->ChunkX) && isset($this->ChunkY) )) {
        $this->ChunkX = $chunkX;
        $this->ChunkY = $chunkY;
    }
    $counter = 0;
    $this->ObjectLocations = array();
    $totalAstroids = $this->GetAstroidNo();


    while ($counter < $totalAstroids) {
        $tempObjectLocations = array();
        //X and Y Chunk Coordinates
        $tempObjectLocations['chunkX'] = $chunkX;
        $tempObjectLocations['chunkY'] = $chunkY;
        //X and Y coordinates for the object.
        $tempObjectLocations['coordX'] = rand(4, 60);
        $tempObjectLocations['coordY'] = rand(4, 60);
        $tempObjectLocations['radius'] = rand(4, 12);
        //Checks if objects already exist in array
        if (count($this->ObjectLocations) > 0) {

            //if the object does not collide with any other object 
            //the location will be added into the database
            if ($this->isColliding($tempObjectLocations) == false) {
                array_push($this->ObjectLocations, $tempObjectLocations);
                $counter += 1;
            }
            // if object is the first created insert into table.
        } else {
            array_push($this->ObjectLocations, $tempObjectLocations);
            $counter += 1;
        }
    }

    return $this->ObjectLocations;
}
public function isColliding($obj1) {
    //Checks if object conflicts with nearby objects
    $a = count($this->ObjectLocations);
    for ($i = 0; $i < $a; $i++) {
        $obj2 = $this->ObjectLocations[$i];

        //Calculates the distance between two points
        $distance = sqrt(($obj1['coordX'] - $obj2['coordX']) ^ 2 + ($obj1['coordY'] - $obj2['coordY']) ^ 2);

        //Checks if the distance between the two objects is 
        //more than the radius of both objects added together
        if ($distance < ($obj1['radius'] + $obj2['radius'] )) {
            return true;
        }
    }
    return false;
}

Json 结果

parseResponse([
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 54,
    "coordY": 17,
    "radius": 8
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 41,
    "coordY": 57,
    "radius": 12
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 42,
    "coordY": 36,
    "radius": 8
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 40,
    "coordY": 58,
    "radius": 8
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 25,
    "coordY": 58,
    "radius": 12
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 57,
    "coordY": 8,
    "radius": 10
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 46,
    "coordY": 17,
    "radius": 11
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 42,
    "coordY": 29,
    "radius": 8
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 18,
    "coordY": 58,
    "radius": 11
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 59,
    "coordY": 5,
    "radius": 11
},
{
    "chunkX": "1",
    "chunkY": "1",
    "coordX": 15,
    "coordY": 56,
    "radius": 12
}

]);

【问题讨论】:

  • 你能用生成的 $this->ObjectLocations 的 var_dump 更新你的问题吗?
  • 等会儿更新一下吧

标签: php arrays logic collision-detection


【解决方案1】:

我有一些提议。在你的isColliding:

public function isColliding($obj1) {
    //Checks if object conflicts with nearby objects
    $a = count($this->ObjectLocations);
    for ($i = 0; $i < $a; $i++) {
        $obj2 = $this->ObjectLocations[$i];

        //Calculates the distance between two points
        $distance = sqrt(($obj1['coordX'] - $obj2['coordX']) ^ 2 + ($obj1['coordY'] - $obj2['coordY']) ^ 2);

        //Checks if the distance between the two objects is 
        //more than the radius of both objects added together
        if ($distance < ($obj1['radius'] + $obj2['radius'] )) { // -> Bad idea !
            return true;
        }
    }
    return false;
}

我标记了不好的地方。为什么 ?因为您将小行星视为质点,但实际上并非如此。如果它们的半径之和等于它们之间的距离,它们仍然会相互碰撞。所以这个条件应该是这样的:

if ($distance <= ($obj1['radius'] + $obj2['radius'] )) { // -> Should work :)
                return true;
            }

每个人都在看,但没有看到。有一些基本错误(当然我也没有看到这个:))。在 PHP 中 ^ 运算符是 XOR 运算符而不是幂运算符 :) 所以你的脚本的正确符号是:

public function isColliding($obj1) {
    //Checks if object conflicts with nearby objects
    $a = count($this->ObjectLocations);
    for ($i = 0; $i < $a; $i++) {
        $obj2 = $this->ObjectLocations[$i];

        //Calculates the distance between two points
//correct ^2 to pow function
        $distance = sqrt(pow($obj1['coordX'] - $obj2['coordX'], 2) + pow($obj1['coordY'] - $obj2['coordY'], 2));

        //Checks if the distance between the two objects is 
        //more than the radius of both objects added together
        if ($distance < ($obj1['radius'] + $obj2['radius'] )) { // -> Bad idea !
            return true;
        }
    }
    return false;
}

【讨论】:

  • 当然比较应该是“
  • @Soyale 很好地抓住了 ^ 运算符。我完全忽略了哈哈:)
  • 感谢我做 php 这么多年,我不知道 ^ 符号,每天学习新东西
【解决方案2】:

也许没有帮助的答案,但是...我认为您的 IF/ELSE 语句应该导致两种不同的状态?

        if ($this->isColliding($tempObjectLocations) == false) {
            array_push($this->ObjectLocations, $tempObjectLocations);
            $counter += 1;
        }
        // if object is the first created insert into table.
    } else {
        array_push($this->ObjectLocations, $tempObjectLocations);
        $counter += 1;
    }

正如我所见,无论它是否碰撞,你都将它推入一个数组中?

【讨论】:

  • 这种情况只是为了防止数组是否为空的冲突检查。他可以省略它,但效果相同,但这只是一种优化。编辑:但我同意它可以写得更好。
  • 好的,很抱歉,但是你在哪里检查它是否碰撞 - 不创建那个对象?在我看来,您永远不会停止在 Generate 方法中创建对象。我的意思是,第一次迭代后数组不为空,然后在第二次迭代中,无论坐标如何,都不会停止创建对象
  • 他正在检查他的 isColliding 方法。
  • 说的很清楚了,但是方法不是用来防止array_push的,不是吗?也许我应该停止评论,觉得自己很愚蠢,没有帮助。
  • if(this->isColliding(..) == false) .. 在您的代码引用的第一行。
猜你喜欢
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 2017-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-26
相关资源
最近更新 更多