function processImage($image) { $orange = imagecolorallocate($image, 220, 210, 60); $black = imagecolorallocate($image, 0, 0, 0); $red = imagecolorallocate($image, 255, 0, 0); $maxX = imagesx($image) - 1; $maxY = imagesy($image) - 1; // Parameters $spread = 1; // Number of pixels to each direction that will be added up $topPositions = 80; // Number of (brightest) lights taken into account $minLightDistance = round(min(array($maxX, $maxY)) / 30); // Minimum number of pixels between the brigtests lights $searchYperX = 5; // spread of the "search beam" from the median point to the top $renderStage = 3; // 1 to 3; exits the process early // STAGE 1 // Calculate the brightness of each pixel (R+G+B) $maxBrightness = 0; $stage1array = array(); for ($row = 0; $row <= $maxY; $row++) { $stage1array[$row] = array(); for ($col = 0; $col <= $maxX; $col++) { $rgb = imagecolorat($image, $col, $row); $brightness = getBrightnessFromRgb($rgb); $stage1array[$row][$col] = $brightness; if ($renderStage == 1) { $brightnessToGrey = round($brightness / 765 * 256); $greyRgb = imagecolorallocate($image, $brightnessToGrey, $brightnessToGrey, $brightnessToGrey); imagesetpixel($image, $col, $row, $greyRgb); } if ($brightness > $maxBrightness) { $maxBrightness = $brightness; if ($renderStage == 1) { imagesetpixel($image, $col, $row, $red); } } } } if ($renderStage == 1) { return; } // STAGE 2 // Add up brightness of neighbouring pixels $stage2array = array(); $maxStage2 = 0; for ($row = 0; $row <= $maxY; $row++) { $stage2array[$row] = array(); for ($col = 0; $col <= $maxX; $col++) { if (!isset($stage2array[$row][$col])) { $stage2array[$row][$col] = 0; } // Look around the current pixel, add brightness for ($y = $row - $spread; $y <= $row + $spread; $y++) { for ($x = $col - $spread; $x <= $col + $spread; $x++) { // Don't read values from outside the image if ($x >= 0 && $x <= $maxX && $y >= 0 && $y <= $maxY) { $stage2array[$row][$col] += $stage1array[$y][$x] + 10; } } } $stage2value = $stage2array[$row][$col]; if ($stage2value > $maxStage2) { $maxStage2 = $stage2value; } } } if ($renderStage >= 2) { // Paint the accumulated light, dimmed by the maximum value from stage 2 for ($row = 0; $row <= $maxY; $row++) { for ($col = 0; $col <= $maxX; $col++) { $brightness = round($stage2array[$row][$col] / $maxStage2 * 255); $greyRgb = imagecolorallocate($image, $brightness, $brightness, $brightness); imagesetpixel($image, $col, $row, $greyRgb); } } } if ($renderStage == 2) { return; } // STAGE 3 // Create a ranking of bright spots (like "Top 20") $topN = array(); for ($row = 0; $row <= $maxY; $row++) { for ($col = 0; $col <= $maxX; $col++) { $stage2Brightness = $stage2array[$row][$col]; $topN[$col . ":" . $row] = $stage2Brightness; } } arsort($topN); $topNused = array(); $topPositionCountdown = $topPositions; if ($renderStage == 3) { foreach ($topN as $key => $val) { if ($topPositionCountdown <= 0) { break; } $position = explode(":", $key); foreach ($topNused as $usedPosition => $usedValue) { $usedPosition = explode(":", $usedPosition); $distance = abs($usedPosition[0] - $position[0]) + abs($usedPosition[1] - $position[1]); if ($distance < $minLightDistance) { continue 2; } } $topNused[$key] = $val; paintCrosshair($image, $position[0], $position[1], $red, 2); $topPositionCountdown--; } } // STAGE 4 // Median of all Top N lights $topNxValues = array(); $topNyValues = array(); foreach ($topNused as $key => $val) { $position = explode(":", $key); array_push($topNxValues, $position[0]); array_push($topNyValues, $position[1]); } $medianXvalue = round(calculate_median($topNxValues)); $medianYvalue = round(calculate_median($topNyValues)); paintCrosshair($image, $medianXvalue, $medianYvalue, $red, 15); // STAGE 5 // Find treetop $filename = 'debug.log'; $handle = fopen($filename, "w"); fwrite($handle, "\n\n STAGE 5"); $treetopX = $medianXvalue; $treetopY = $medianYvalue; $searchXmin = $medianXvalue; $searchXmax = $medianXvalue; $width = 0; for ($y = $medianYvalue; $y >= 0; $y--) { fwrite($handle, "\nAt y = " . $y); if ($y % $searchYperX == 0) { // Modulo $width++; $searchXmin = $medianXvalue - $width; $searchXmax = $medianXvalue + $width; imagesetpixel($image, $searchXmin, $y, $red); imagesetpixel($image, $searchXmax, $y, $red); } foreach ($topNused as $key => $val) { $position = explode(":", $key); // "x:y" if ($position[1] != $y) { continue; } if ($position[0] >= $searchXmin && $position[0] <= $searchXmax) { $treetopX = $position[0]; $treetopY = $y; } } } paintCrosshair($image, $treetopX, $treetopY, $red, 5); // STAGE 6 // Find tree sides fwrite($handle, "\n\n STAGE 6"); $treesideAngle = 60; // The extremely "fat" end of a christmas tree $treeBottomY = $treetopY; $topPositionsExcluded = 0; $xymultiplier = 0; while ($topPositionsExcluded < $topPositions / 5 && $treesideAngle >= 1) { fwrite($handle, "\n\nWe're at angle " . $treesideAngle); $xymultiplier = sin(deg2rad($treesideAngle)); fwrite($handle, "\nMultiplier: " . $xymultiplier); $topPositionsExcluded = 0; foreach ($topNused as $key => $val) { $position = explode(":", $key); fwrite($handle, "\nAt position " . $key); if ($position[1] > $treeBottomY) { $treeBottomY = $position[1]; } // Lights above the tree are outside of it, but don't matter if ($position[1] < $treetopY) { $topPositionsExcluded++; fwrite($handle, "\nTOO HIGH"); continue; } // Top light will generate division by zero if ($treetopY - $position[1] == 0) { fwrite($handle, "\nDIVISION BY ZERO"); continue; } // Lights left end right of it are also not inside fwrite($handle, "\nLight position factor: " . abs($treetopX - $position[0]) / abs($treetopY - $position[1])); if (abs($treetopX - $position[0]) / abs($treetopY - $position[1]) > $xymultiplier) { $topPositionsExcluded++; fwrite($handle, "\n --- Outside tree ---"); } } $treesideAngle--; } fclose($handle); // Paint tree's outline $treeHeight = abs($treetopY - $treeBottomY); $treeBottomLeft = 0; $treeBottomRight = 0; $previousState = false; // line has not started; assumes the tree does not "leave"^^ for ($x = 0; $x <= $maxX; $x++) { if (abs($treetopX - $x) != 0 && abs($treetopX - $x) / $treeHeight > $xymultiplier) { if ($previousState == true) { $treeBottomRight = $x; $previousState = false; } continue; } imagesetpixel($image, $x, $treeBottomY, $red); if ($previousState == false) { $treeBottomLeft = $x; $previousState = true; } } imageline($image, $treeBottomLeft, $treeBottomY, $treetopX, $treetopY, $red); imageline($image, $treeBottomRight, $treeBottomY, $treetopX, $treetopY, $red); // Print out some parameters $string = "Min dist: " . $minLightDistance . " | Tree angle: " . $treesideAngle . " deg | Tree bottom: " . $treeBottomY; $px = (imagesx($image) - 6.5 * strlen($string)) / 2; imagestring($image, 2, $px, 5, $string, $orange); return $topN; }
/** * Calculate average daily prices for all items across all defined market systems for the specified date, and save * average and median prices in the historicalprices table. * @param str $datetime A datetime in Y-m-d H:i:s format * @return bool A boolean indicating database update success or failure. */ public function processDailyHistoricalPrices($datetime) { $date = date("Y-m-d", strtotime($datetime)); //Retrieve system and type IDs as iterative arrays $systemIDs = array_keys($this->getAllSystems()); $systemID = null; $typeIDs = array_keys($this->getAllTypes()); $typeID = null; //Define new array for the update statements (tuples) $tuples = array(); $sql = "SELECT maxBuy, minSell\n FROM {$this->dbPrefix}prices\n WHERE typeID=:t AND systemID=:s AND datetime LIKE '{$date}%';"; $query = $this->pdo->prepare($sql); $query->bindParam(":t", $typeID, PDO::PARAM_INT); $query->bindParam(":s", $systemID, PDO::PARAM_INT); foreach ($systemIDs as $systemID) { foreach ($typeIDs as $typeID) { // Execute DB query with current typeID/systemID $query->execute(); // Initialize array for price data $maxBuys = array(); $minSells = array(); // Populate price arrays with query results while ($row = $query->fetch(PDO::FETCH_ASSOC)) { //Push respective prices to their own arrays array_push($maxBuys, $row['maxBuy']); array_push($minSells, $row['minSell']); } //Calculate average of prices, format update record and push to updates array if (count($maxBuys) >= 2) { $avgMaxBuy = round(array_sum($maxBuys) / count($maxBuys), 2); $medMaxBuy = calculate_median($maxBuys); } elseif (count($maxBuys) == 1) { $avgMaxBuy = $maxBuys[0]; $medMaxBuy = $maxBuys[0]; } else { $avgMaxBuy = 0; $medMaxBuy = 0; } if (count($minSells) >= 2) { $avgMinSell = round(array_sum($minSells) / count($minSells), 2); $medMinSell = calculate_median($minSells); } elseif (count($minSells) == 1) { $avgMinSell = $minSells[0]; $medMinSell = $minSells[0]; } else { $avgMinSell = 0; $medMinSell = 0; } $tuple = "({$systemID},{$typeID},'{$date} 00:00:00',{$avgMaxBuy},{$medMaxBuy},{$avgMinSell},{$medMinSell})"; array_push($tuples, $tuple); } } //Implode updates array to create comma-separated string to feed into SQL query $tupleStr = implode(",", $tuples); $sql = "INSERT INTO {$this->dbPrefix}historicalprices \n (systemID, typeID, datetime, avgMaxBuy, medMaxBuy, \n avgMinSell, medMinSell)\n VALUES {$tupleStr}\n ON DUPLICATE KEY UPDATE \n avgMaxBuy=VALUES(avgMaxBuy), \n medMaxBuy=VALUES(medMaxBuy), \n avgMinSell=VALUES(avgMinSell), \n medMinSell=VALUES(medMinSell);"; $statement = $this->pdo->prepare($sql); $result = $statement->execute(); $statement->closeCursor(); $statement = null; return $result; }
function calculateRating($project_id) { global $db_con; $query = 'SELECT `project_id` FROM `projects`'; $projects = $db_con->sql2array($query); $rates = array(); foreach ($projects as $project) { $rates[] = getTotalRatingsForProject($project['project_id']); } $mn = calculate_median($rates); $project_count = count($projects); $m = round(getTotalRatings() / $project_count, 3); $mr = calculate_mr($project_id); $nr = getTotalRatingVaueForProject($project_id); if ($mr == 'N/A') { return $mr; } return @round(($m * $mn + $nr * $mr) / ($mn + $nr), 2); }