Build 2D Array of Canvas RGB values - php

I'm trying to send a 2D array of RGB values to PHP from the array of values from the getImageData().data method:
for (var i=0;i<imgData.data.length;i+=4){
// If you want to know the values of the pixel
var r = imgData.data[i + 0];
var g = imgData.data[i + 1];
var b = imgData.data[i + 2];
var a = imgData.data[i + 3];
//[...] do what you want with these values
}
From this, how would I create a 2D array of RGB values of an entire canvas?

var rgb = [];
for (var i=0;i<imgData.data.length;i+=4){
// If you want to know the values of the pixel
var r = imgData.data[i + 0];
var g = imgData.data[i + 1];
var b = imgData.data[i + 2];
var a = imgData.data[i + 3];
var x = Math.floor((i/4) % imageData.width);
var y = Math.floor((i/4) / imageData.width);
rgb[x] ? (rgb[x][y] = [r,b,g,a]) : (rgb[x] = [[r,b,g,a]]);
}

This may not be what you want, but if your concern is transferring the image data (not necessarily building an array on the client side), toDataURL() might be an even simpler way to transfer your image data...
The HTML5 canvas.toDataURL('image/png') method will produce a data URI for your image data - i.e. a really long, text-encoded version of the PNG. No need to grab the image data manually. Likewise, you could use a JPEG encoding if that's preferable.
If you send this string to the server, PHP can decoded back to binary form directly by passing it as the first argument to file_get_contents() (i.e. $binary = file_get_contents($dataURL)). You can then save this to disk or do whatever you want with the binary PNG data as you would with a file you had just loaded off disk.

Related

Get itinerary latitudes & longitude from google maps with PHP

I want to list the latitude and longitude of itinerary. It could be all points or it could be all points in 1-2 kilometers.
What I'm trying to do is: user selected A as the starting point and B as the ending point. I want to show some places near the road between A and B on the map. But I need a positions for this.
As an example, a JavaScript code is shared here and It is said that this can be done with DirectionsResult Object.
var request = {
origin: start_point,
destination: end_point,
travelMode: google.maps.TravelMode.DRIVING
};
var directionsService = new google.maps.DirectionsService();
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
var path = (response.routes[0].overview_path);
}
});
But I'm trying to do this with php and I have to do this with php.
I read google map api. I've also read the yandex map api, but this seems to be done only with javascript.
Does anyone know a way to do this with php?
From comments I understand the question is to find (using PHP) the intermediate lat,lng pairs that can be extracted from the polyline points in a google directions query.
This is a bit unusual because people normally use the polyline points for map drawing in the browser, and so the JavaScript libraries are well equipped for this task. However, not so in PHP.
The points data appears in the JSON result object as string of ascii characters, sometimes quite long and always 'unreadable'. Into this string is encoded a list of intermediate lat lng pairs between the start and end of each leg. The coding method is presented at the google site https://developers.google.com/maps/documentation/utilities/polylinealgorithm and the algorithm below is just a reversal of that and is commented accordingly.
The example shows a directions find between 2 points, on crescent shaped streets, in Perth, Australia. The start-end points were chosen to encourage multiple intermediate points as would be needed to draw the route. Substitute your own search as needed.
Note that the JSON also provides these fields also at the end of each results object.
"overview_polyline" : {
"points" : "~n{aEmbwaU_B#cCBk#Lo#d#UVOb#Mh#Ab####BBF#DGNABD`#Fh#Pb#VZn#b#d#J"
},
This is much less detailed and less accurate (if you draw will probably depart from actual road lines on map), but can also be decoded in the same way.
The best intermediate points are however, by iterating through the steps using:
"polyline" : {
"points" : "~n{aEmbwaUg##w#?{A?g#BUBUHSJ[XUVOb#Mh#Ab#"
},
Finally, the original source for the algorithm can be found here http://unitstep.net/blog/2008/08/02/decoding-google-maps-encoded-polylines-using-php/. So thanks to Peter Chng for this work back in 2008! Peter also acknowledges Mark MClure who did the original coding in JavaScript. I hacked about with and added more comments - to make more aligned with the google recipe, but no more.
I have also just realised there is this link https://github.com/emcconville/google-map-polyline-encoding-tool which (I think but have not tested) provides a class and a CLI tool to do the conversions both ways.
$json = file_get_contents("https://maps.googleapis.com/maps/api/directions/json?origin=20%20%20Kintyre%20Crescent,%20Churchlands&destination=%2018Kinross%20Crescent,%20Churchlands&key=");
$details = json_decode($json,true);
print_r($details); // show the full result
$points = $details['routes'][0]['legs'][0]['steps'][0]['polyline']['points'];
echo($points); // show the points string for one leg
// show the start and end locations for that leg
print_r($details['routes'][0]['legs'][0]['steps'][0]['start_location']);
print_r($details['routes'][0]['legs'][0]['steps'][0]['end_location']);
// work out the intermdiate points (normally used for drawing)
$decodedPoints= decodePolylinePoints($points);
print_r($decodedPoints); // print out the intermediate points
// This function decodes the polylone points in PHP
function decodePolylinePoints($pointsString)
{
$len = strlen($pointsString);
$latLons = array(); // the output array
$lat = 0; // temp storage for lat and lng
$lng = 0;
$index = 0; // index to curent character
while ($index < $len) // process each lat,lng pair
{
// first build the lat
// NOTE: first lat is an absolute value
// NOTE: subsequent lats are offsets from previous values for coding efficiency
$char = 0; // char as read from points string
$shift = 0; // cumulative shift amount
$value = 0; // temp value during computation
do // Read, convert and shift 5 bit chunks until terminator is reached to get lat
{
$char = ord(substr($pointsString, $index++)) - 63; // return ascii value less 63
$value |= ($char & 0x1f) << $shift; // convert to 5 bit and shift left
$shift += 5; // next shift is 5 extra
}
while ($char >= 0x20); // value of 20 indicates end of lat
$lat += (($value & 1) ? ~($value >> 1) : ($value >> 1)); // convert negative values and save
// now build the lng
// NOTE: first lng is an absolute value
// NOTE: subsequent lngs are offsets from previous values for coding efficiency
$shift = 0;
$value = 0;
do // build up lng from 5 bit chunks
{
$char= ord(substr($pointsString, $index++)) - 63; // return ascii value less 63
$value |= ($char & 0x1f) << $shift; // convert to 5 bit and shift left
$shift += 5; // next shift is 5 extra
}
while ($char >= 0x20); // value of 20 indicates end of lng
$lng += (($value & 1) ? ~($value >> 1) : ($value >> 1)); // convert negative values and save
$latLons[] = array($lat * 1e-5, $lng * 1e-5); // original values were * 1e5
}
return $latLons; // points array converted to lat,lngs
}

Reflection Inside Circle Over Time

This is for a game that I am considering.
I have a point that is noted as moving inside a (2D) circle from an arbitrary point, at an arbitrary direction and at a particular time. The point will bounce off the interior wall of the circle when it intersects.
For this example let's say the circle has a diameter of 100 kilometers with it's center at (0,0) and 10 hours ago the point was at location (20,30) with a heading of 40 degrees at a speed of 50kph .
What is the best way to determine where that point currently is and at what direction it's traveling?
I will be implementing this in PHP with the point and circle data stored in MySQL. Since it is a web page there will be no constantly running host process to keep things up to date and the data will need to be refreshed upon a page load.
I'm certainly not looking for anyone to write the code for me but am hoping someone can help me with a somewhat efficient way to approach this.
Your point-object will travel along what is called chords in geometry.
As the object hits the circle boundary, it will reflect from the circle's tangent at that point, and go along a next chord that has the same length. The next hit will be at the same angle (with the tangent at that hit point) as the previous hit, and so it will continue. At a constant speed, the time between hits will be a constant time.
Given the start time and the current time, one can calculate the number of chords that have been completed, and how much of the current chord has been completed. Calculating the position from that is easy when you know the previous and next hit positions. As these hit positions are at equal distances along the circle boundary, that is a matter of converting polar coordinates (an angle, and a distance of 1 radian) to Cartesian coordinates.
I will demonstrate this with JavaScript code. It will not be a great effort to wrap this in PHP:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var radius = canvas.height / 2 - 5;
var pixel = 1/radius;
// transform the canvas so that 0,0 is in the center of the canvas,
// and a unit circle would cover most of the height of the canvas:
context.setTransform(radius, 0, 0, radius, radius+2, radius+2);
// draw unit circle
context.beginPath();
context.arc(0, 0, 1, 0, 2 * Math.PI, false);
context.lineWidth = pixel;
context.strokeStyle = 'black';
context.stroke();
function drawPoint(point) {
// use a different color every 30 seconds:
context.fillStyle = Date.now() % 60000 > 30000 ? 'red' : 'blue';
context.fillRect(point.x-2*pixel, point.y-2*pixel, 4*pixel, 4*pixel);
}
function polarToCartesian(rad, dist) {
return {
x: Math.cos(rad) * dist,
y: Math.sin(rad) * dist
}
}
function pointBetween(a, b, fractionTravelled) {
return {
x: a.x + (b.x-a.x)*fractionTravelled,
y: a.y + (b.y-a.y)*fractionTravelled
}
}
// 4 parameters are needed:
var startRadians = 0; // distance along circle boundary from (0,1)
var hitAngle = Math.PI/2.931; // PI/2 would be head-on impact along diagonal
var speed = 0.4; // radians per second
var startTime = Date.now()/1000; // seconds
//
// Calculate some derived values which remain constant:
// - theta as used on https://en.wikipedia.org/wiki/Chord_%28geometry%29
// - chordSize formula comes from that wiki article.
var theta = 2 * hitAngle;
var chordSize = 2 * Math.sin(theta/2); // in radians
function drawCurrentPosition() {
// Note that this calculation does not look at the previous result,
// but uses the original parameters and time passed to calculate
// the objects current position.
var elapsedTime = Date.now()/1000 - startTime; // in secs
var distanceTravelled = speed * elapsedTime; // in radians
var chordsTravelled = distanceTravelled / chordSize; // in number of chords
var chordsTravelledComplete = Math.floor(chordsTravelled);
var fractionOnChord = chordsTravelled - chordsTravelledComplete; // 0<=f<1
var lastHitRadians = startRadians + chordsTravelledComplete * theta; // rad
var nextHitRadians = lastHitRadians + theta;
var lastHitPos = polarToCartesian(lastHitRadians, 1); // (x,y)
var nextHitPos = polarToCartesian(nextHitRadians, 1);
var currentPos = pointBetween(lastHitPos, nextHitPos, fractionOnChord);
drawPoint(currentPos);
}
// Demo: keep drawing the object's position every 0.1 second:
setInterval(drawCurrentPosition, 100);
<canvas id="myCanvas" width="200" height="200"></canvas>
Addendum: PHP code
Here is some code that could be useful for use in PHP. It uses the same calculations as the above JavaScript code, but does not keep running. Instead it first checks if there is a started game in the session scope, if not, it starts the "clock". At every request (reload of the page), the new position is calculated and printed on the page as an X,Y pair.
The coordinates are normalised, based on a unit circle (radius 1). The game parameters are hard-coded, but you could easily let them be passed via POST/GET parameters:
session_start(); // needed to persist game data for this user session
function getNewGame($startRadians, $hitAngle, $speed) {
$game = array();
$game["startTime"] = microtime(true);
$game["startRadians"] = $startRadians;
$game["theta"] = 2 * $hitAngle;
$game["chordSize"] = 2 * sin($hitAngle);
$game["speed"] = $speed;
return (object) $game;
}
function polarToCartesian($rad, $dist) {
return (object) array(
"x" => cos($rad) * $dist,
"y" => sin($rad) * $dist
);
}
function pointBetween($a, $b, $fractionTravelled) {
return (object) array(
"x" => $a->x + ($b->x-$a->x)*$fractionTravelled,
"y" => $a->y + ($b->y-$a->y)*$fractionTravelled
);
}
function getCurrentPosition($game) {
// Note that this calculation does not look at the previous result,
// but uses the original parameters and time passed to calculate
// the objects current position.
$elapsedTime = microtime(true) - $game->startTime; // in secs
$distanceTravelled = $game->speed * $elapsedTime; // in radians
$chordsTravelled = $distanceTravelled / $game->chordSize; //number of chords
$chordsTravelledComplete = floor($chordsTravelled);
$fractionOnChord = $chordsTravelled - $chordsTravelledComplete; // 0<=f<1
$lastHitRadians = $game->startRadians
+ $chordsTravelledComplete * $game->theta; // in radians on circle
$nextHitRadians = $lastHitRadians + $game->theta;
$lastHitPos = polarToCartesian($lastHitRadians, 1); // (x,y)
$nextHitPos = polarToCartesian($nextHitRadians, 1);
$currentPos = pointBetween($lastHitPos, $nextHitPos, $fractionOnChord);
return $currentPos;
}
// check if this is the first time the user loads this page:
if (!isset($_SESSION["game"])) {
// start game with some game parameters:
$_SESSION["game"] = getNewGame(0, pi()/2.931, 0.4);
}
// calculate the position based on game info and current time:
$pos = getCurrentPosition($_SESSION["game"]);
// print the result:
echo "Current position: {$pos->x}, {$pos->y}<br>";

How to rotate object about x-axis

I'm trying to rotate some 3d objects about the x-axis (I don't need to rotate them on their center so no need to translate to 0,0,0 first then back to their original position). I've just written a quick php script to test it out on an obj file. I've checked out the Wikipedia page for matrix rotation and was pretty confident my code would work...
CreateXrotationMatrix takes an angle and creates the required rotation matrix from
[1 0 0 ]
Rx(α)=[0 cosα -sinα]
[0 sinα cosα ]
function CreateXrotationMatrix($alpha)
{
$matrix = Array();
$matrix[0] = 1;
$matrix[1] = 0;
$matrix[2] = 0;
$matrix[3] = 0;
$matrix[4] = cos($alpha);
$matrix[5] = -sin($alpha);
$matrix[6] = 0;
$matrix[7] = sin($alpha);
$matrix[8] = cos($alpha);
return $matrix;
}
MultiplyMatrices then multiplies a 3x3 matrix by a given point
function MultiplyMatrices($rotationMatrix, $point)
{
$returnMatrix = Array();
$returnMatrix[0] = $rotationMatrix[0]*$point[0] + $rotationMatrix[1]*$point[1] + $rotationMatrix[2]*$point[2];
$returnMatrix[1] = $rotationMatrix[3]*$point[0] + $rotationMatrix[4]*$point[1] + $rotationMatrix[4]*$point[2];
$returnMatrix[2] = $rotationMatrix[6]*$point[0] + $rotationMatrix[7]*$point[1] + $rotationMatrix[8]*$point[2];
return $returnMatrix;
}
I ran this code on an obj file which I tried to rotate by 270 degrees and wrote it out to another file.
When I got the two models side by side in blender they were only 10 degrees apart.
Any ideas what's wrong here?

How to truncate filename from end with limit

Let's say we have three file names:
var a = "01704_0047a_05a_canvas.jpg";
var b = "101704_0047a_05a_canvas.jpg";
var c = "foo.jpg";
Obviously the three are 1 character different, this is just to illustrate that the filenames will vary in length, what I'm aiming to do, is only display the last 10 characters from the end, regardless of the length of the filename, Results:
var a = "canvas.jpg";
var b = "canvas.jpg";
var c = "foo.jpg";
here's what I've tried:
a.substring(a.length, 10);
This seems to give me different results thought, ideas?
I also need to mimic the same result in php if someone feels generous!
Javascript
var a = "01704_0047a_05a_canvas.jpg";
console.log(a.substr(-10)); // OR a.substring(a.length - 10, a.length);
PHP
$a = "01704_0047a_05a_canvas.jpg";
echo substr($a, -10);
References:
Javascript
[substr] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr
[substring] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring
PHP
[substr] http://php.net/substr

Simple Javascript encrypt, PHP decrypt with shared secret key

This is not about security. It is also not to make it hard to break. I'm looking for a simple algorithm to change a string (a url) in a way it does not resemble the original. The encryption will be done with javascript. Then I want to feed the encrypted string to a PHP function to change it back to the original. Both ends could share a secret key, or the conversions could be key-less and rely on just logic.
The ideal solution
will be simple
will use available javascript functions for encryption
will use available php functions for decryption
will produce encrypted string in way not to resemble the plain text at all
will only use lower-case alphabet characters and numbers in the encrypted string
is not a method widely used like Base64-ing as encryption.
Edit: The last requirement was added after shamittomar's answer.
You can use bitwise XOR in javascript to encode the string and again in PHP to decode it again. I wrote a little Javascript example for you. It works the same in PHP. If you call enc() a second time with the already encoded string, you'll get the original string again.
<html>
<head><title></title></head>
<body>
<script type="text/javascript">
function enc(str) {
var encoded = "";
for (i=0; i<str.length;i++) {
var a = str.charCodeAt(i);
var b = a ^ 123; // bitwise XOR with any number, e.g. 123
encoded = encoded+String.fromCharCode(b);
}
return encoded;
}
var str = "hello world";
var encoded = enc(str);
alert(encoded); // shows encoded string
alert(enc(encoded)); // shows the original string again
</script>
</body>
</html>
In PHP do something like this (caution, this is not tested and it's been a long while since I did PHP):
$encoded = "..."; // <-- encoded string from the request
$decoded = "";
for( $i = 0; $i < strlen($encoded); $i++ ) {
$b = ord($encoded[$i]);
$a = $b ^ 123; // <-- must be same number used to encode the character
$decoded .= chr($a)
}
echo $decoded;
If that's what you want, you can Base64 encode and decode that.
[EDIT]: After OP clarification:
As you do not want widely used methods, here is one rarely used method and that can do it for you by giving output only in LOWERCASE letters and NUMBERS. It is Base32 Encode/Decode. Use the following libraries:
Javascript Base32 Encoder: http://www.tumuski.com/2010/04/nibbler/
PHP Base32 Decoder: https://www.phpclasses.org/package/3484-PHP-Encode-and-decode-data-with-MIME-base-32-encoding.html
If it's not about security, and not about making it hard to break, then how about ROT-13?
//+ Jonas Raoni Soares Silva
//# http://jsfromhell.com/string/rot13 [rev. #1]
String.prototype.rot13 = function(){
return this.replace(/[a-zA-Z]/g, function(c){
return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
});
};
...
var s = "My String";
var enc = s.rot13(); // encrypted value in enc
PHP has a native function, str_rot13: http://php.net/manual/en/function.str-rot13.php
$decrypted = str_rot13($_GET['whatever']);
Well I found this page and found Redcully's program not work for me so I thought It happens with all others. finally I got reason and fixed it. Here new code is...
Thanks to Redcully :)
JS function:
function encode(str) {
var encoded = "";
for (i=0; i<str.length;i++) {
var a = str.charCodeAt(i);
var b = a ^ 51; // bitwise XOR with any number, e.g. 123
encoded = encoded+String.fromCharCode(b);
}
return encoded;
}
PHP function:
function decode($encoded) {
$decoded = "";
for( $i = 0; $i < strlen($encoded); $i++ ) {
$b = ord($encoded[$i]);
$a = $b ^ 51; // <-- must be same number used to encode the character
$decoded .= chr($a);
}
return $decoded;
}
How are you planning to implement (hide) the secret in Javascript? IMHO it's not possible.
Edit: OK - not about security.. then just use any baseXX or rot encoding mechanism. But you can't really say one of these algorythms would not be well known...

Categories