How to avoid errors in trigonometry functions in Oracle? - oracle

I have a curson in my stored procedure
SELECT a.id, a.full_address, me.answer medid, me.name NAME, a.nlat, a.nlong, a.parent_table
FROM example_table_1 a,
(SELECT pnradius AS radius,
111.045 AS distance_unit,
57.2957795 AS rad2deg,
0.01745329251994 AS deg2rad
FROM dual) geo,
example_table me
WHERE a.nlat BETWEEN pnlatitude - (geo.radius / geo.distance_unit) AND
pnlatitude + (geo.radius / geo.distance_unit)
AND a.nlong BETWEEN pnlongitude - (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude)))) AND
pnlongitude + (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
AND geo.distance_unit * rad2deg *
(acos(cos(deg2rad * (pnlatitude)) * cos(deg2rad * (a.nlat)) * cos(deg2rad * (pnlongitude - a.nlong)) +
sin(deg2rad * (pnlatitude)) * sin(deg2rad * (a.nlat)))) < pnradius
AND a.parent_id = me.answer
AND a.parent_table = 'example_table'
pnlatitude and pnlongiture are paramenters of procedure.
In most cases this cursor works great. But sometimes in some areas in Russia this cursor cause this error:
I understand what is going on here, but I can't track where does it happen. I can adjust deg2rad value and it helps, but then this error will appear with other coordinates.
Is it possible to reduce the value of trigonometry function paramentr to 1 when it is more than 1?

Use the LEAST function to ensure you don't pass an argument greater than 1 to ACOS:
SELECT a.id, a.full_address, me.answer medid, me.name NAME, a.nlat, a.nlong, a.parent_table
FROM example_table_1 a,
(SELECT pnradius AS radius,
111.045 AS distance_unit,
57.2957795 AS rad2deg,
0.01745329251994 AS deg2rad
FROM dual) geo,
example_table me
WHERE a.nlat BETWEEN pnlatitude - (geo.radius / geo.distance_unit)
AND pnlatitude + (geo.radius / geo.distance_unit)
AND a.nlong BETWEEN pnlongitude - (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
AND pnlongitude + (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
AND geo.distance_unit * rad2deg *
(acos(LEAST(cos(deg2rad * (pnlatitude)) * cos(deg2rad * (a.nlat)) * cos(deg2rad * (pnlongitude - a.nlong)) +
sin(deg2rad * (pnlatitude)) * sin(deg2rad * (a.nlat)), 1))) < pnradius
AND a.parent_id = me.answer
AND a.parent_table = 'example_table'
This is the same as your original with a LEAST(big-long-calc, 1) added inside the ACOS call. Hopefully I counted the parentheses right - if not, adjust as necessary. :-)
Best of luck.

Related

How to calculate latitude and longitude based on distance in laravel

This is my function
public function getRshow(){
$lats = $tenl[0]->latitude;
$longs = $tlog[0]->longitude;
$distance =$par_dis[0]->partner_distance;
$project = "SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(( $lats - latitude) * pi()/180 / 2), 2) +COS( $lats * pi()/180) * COS(latitude * pi()/180) * POWER(SIN(( $longs - longitude) * pi()/180 / 2), 2) ))) as distance
FROM `abserve_renterpost` having distance <= $distance order by distance";
$la=DB::SELECT($project);
$lara=array();
foreach ($project as $key => $v) {
$lara[]=(get_object_vars($v));
}
}
My query is working good if I run only the query, but if I converted my query for value and array format it's not working, error is displayed as below.
(SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' - latitude) * pi()/180 / 2), 2) +COS( 27.7 * pi()/180) * COS(latitude * ' at line 1 (SQL: SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(( 27.7 - latitude) * pi()/180 / 2), 2) +COS( 27.7 * pi()/180) * COS(latitude * pi()/180) * POWER(SIN(( 74.12399600000003
- longitude) * pi()/180 / 2), 2) ))) as distance
FROM `abserve_renterpost` having distance <= 200 order by distance))
I noticed $lats was 27.7 which is odd.
try this
$lats = $tenl[0]->latitude;
$longs = $tlog[0]->longitude;
$distance =$par_dis[0]->partner_distance;
$project = <<<SQL
SELECT * , (3956 * 2 * ASIN(
SQRT(
POWER(SIN(($lats - `latitude`) * pi() / 180 / 2), 2)
+ COS($lats * pi() / 180)
* COS(`latitude` * pi() / 180)
* POWER(SIN(($longs - `longitude`) * pi() / 180 / 2), 2)
))
) as 'distance'
FROM `abserve_renterpost`
WHERE distance <= $distance
ORDER BY distance;
SQL;
$la=DB::select($project);
$lara=array();
foreach ($project as $key => $v) {
$lara[]=(get_object_vars($v));
}

break a long list into multiple columns in restructured text

Is there a way to break a long list into multiple columns in restructured text?
source:
* a
* b
* c
* d
* e
* a
* c
* a
* d
* e
* f
result:
* a * e * d
* b * a * e
* c * c * f
* d * a
The goal is to provide the source list in a reST directive
rather than using some other language to read the source list and then write the result text with the ".. raw::" directive in reST. Such as this hypothetical list-multicol directive:
.. list-multicol::
:columns: 3
* a
* b
* c
* d
* e
* a
* c
* a
* d
* e
* f
Extra credit for option to balance columns (same number of items +/- 1) no wider than the page or a specified number of columns.
Apparently, the hlist directive does this.
http://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-hlist
Here's the example:
.. hlist::
:columns: 3
* A list of
* short items
* that should be
* displayed
* horizontally

Escape values in multiples DB raw select in Laravel 4

In my query I have something like:
->select('User.id', 'city', 'lat', 'lng', 'comment', 'Comments.created_at', 'disponibility',
DB::raw("User.*, (count(Comments.user_id)) as note_count"),
DB::raw("User.*, (3956 * 2 * ASIN(SQRT( POWER(SIN((:lat - lat) * pi()/180 / 2), 2) +COS(:lat * pi()/180) * COS(lat * pi()/180) * POWER(SIN((:lng - lng) * pi()/180 / 2), 2) ))/0.621371192) as distance"),
["lat" => $lat, "lng" => $lng]
)
For a reason, it give me error that I don't know why
strtolower() expects parameter 1 to be string, array given
Anyone can help me please?
Much appreciated
The problem here is probably that you put your binding not as 2nd argument for DB::raw but as argument for select method.
Just try instead of above code:
->select('User.id', 'city', 'lat', 'lng', 'comment', 'Comments.created_at', 'disponibility',
DB::raw("User.*, (count(Comments.user_id)) as note_count"),
DB::raw("User.*, (3956 * 2 * ASIN(SQRT( POWER(SIN((:lat - lat) * pi()/180 / 2), 2) +COS(:lat * pi()/180) * COS(lat * pi()/180) * POWER(SIN((:lng - lng) * pi()/180 / 2), 2) ))/0.621371192) as distance", ["lat" => $lat, "lng" => $lng])
)

Square with diagonal in Pascal

I have written an application which will write square with diagonal (from left side) - output:
+ * * * *
* + * * *
* * + * *
* * * + *
* * * * +
Code for first application:
PROGRAM cycle4;
USES CRT;
VAR a,r,s:INTEGER;
BEGIN
CLRSCR;
WRITE (‘Enter the number of lines :‘) ;
READLN(a);
FOR r:= 1 TO a DO
BEGIN
FOR s:=1 TO a DO
IF r = s THEN WRITE(‘+‘)
ELSE WRITE(‘*‘) ;
WRITELN;
END;
READLN;
END.
And now I have to create an application which will write square with diagonal (from right side) - output:
* * * * +
* * * + *
* * + * *
* + * * *
+ * * * *
But I don't know how can I write it. Can you help me?
Thanks :)
The line of code which defines the position of + sign is that:
IF r = s THEN WRITE(‘+‘)
and this is the only line you need to change:
IF r + s = a + 1 THEN WRITE(‘+‘)
I think this should work, check with Pascal compiler, haven't used it for about 10 years :)

Circle-Circle Collision Prediction

I'm aware of how to check if two circles are intersecting one another. However, sometimes the circles move too fast and end up avoiding collision on the next frame.
My current solution to the problem is to check circle-circle collision an arbitrary amount of times between the previous position and it's current position.
Is there a mathematical way to find the time it takes for the two circle to collide? If I was able to get that time value, I could move the circle to the position at that time and then collide them at that point.
Edit: Constant Velocity
I'm assuming the motion of the circles is linear. Let's say the position of circle A's centre is given by the vector equation Ca = Oa + t*Da where
Ca = (Cax, Cay) is the current position
Oa = (Oax, Oay) is the starting position
t is the elapsed time
Da = (Dax, Day) is the displacement per unit of time (velocity).
Likewise for circle B's centre: Cb = Ob + t*Db.
Then you want to find t such that ||Ca - Cb|| = (ra + rb) where ra and rb are the radii of circles A and B respectively.
Squaring both sides:
||Ca-Cb||^2 = (ra+rb)^2
and expanding:
(Oax + t*Dax - Obx - t*Dbx)^2 + (Oay + t*Day - Oby - t*Dby)^2 = (ra + rb)^2
From that you should get a quadratic polynomial that you can solve for t (if such a t exists).
Here is a way to solve for t the equation in Andrew Durward's excellent answer.
To just plug in values one can skip to the bottom.
(Oax + t*Dax - Obx - t*Dbx)^2 + (Oay + t*Day - Oby - t*Dby)^2 = (ra + rb)^2
(Oax * (Oax + t*Dax - Obx - t*Dbx) + t*Dax * (Oax + t*Dax - Obx - t*Dbx)
- Obx * (Oax + t*Dax - Obx - t*Dbx) - t*Dbx * (Oax + t*Dax - Obx - t*Dbx))
+
(Oay * (Oay + t*Day - Oby - t*Dby) + t*Day * (Oay + t*Day - Oby - t*Dby)
- Oby * (Oay + t*Day - Oby - t*Dby) - t*Dby * (Oay + t*Day - Oby - t*Dby))
=
(ra + rb)^2
Oax^2 + (Oax * t*Dax) - (Oax * Obx) - (Oax * t*Dbx)
+ (t*Dax * Oax) + (t*Dax)^2 - (t*Dax * Obx) - (t*Dax * t*Dbx)
- (Obx * Oax) - (Obx * t*Dax) + Obx^2 + (Obx * t*Dbx)
- (t*Dbx * Oax) - (t*Dbx * t*Dax) + (t*Dbx * Obx) + (t*Dbx)^2
+
Oay^2 + (Oay * t*Day) - (Oay * Oby) - (Oay * t*Dby)
+ (t*Day * Oay) + (t*Day)^2 - (t*Day * Oby) - (t*Day * t*Dby)
- (Oby * Oay) - (Oby * t*Day) + Oby^2 + (Oby * t*Dby)
- (t*Dby * Oay) - (t*Dby * t*Day) + (t*Dby * Oby) + (t*Dby)^2
=
(ra + rb)^2
t^2 * (Dax^2 + Dbx^2 - (Dax * Dbx) - (Dbx * Dax)
+ Day^2 + Dby^2 - (Day * Dby) - (Dby * Day))
+
t * ((Oax * Dax) - (Oax * Dbx) + (Dax * Oax) - (Dax * Obx)
- (Obx * Dax) + (Obx * Dbx) - (Dbx * Oax) + (Dbx * Obx)
+ (Oay * Day) - (Oay * Dby) + (Day * Oay) - (Day * Oby)
- (Oby * Day) + (Oby * Dby) - (Dby * Oay) + (Dby * Oby))
+
Oax^2 - (Oax * Obx) - (Obx * Oax) + Obx^2
+ Oay^2 - (Oay * Oby) - (Oby * Oay) + Oby^2 - (ra + rb)^2
=
0
Now it's a standard form quadratic equation:
ax2 + bx + c = 0
solved like this:
x = (−b ± sqrt(b^2 - 4ac)) / 2a // this x here is t
where--
a = Dax^2 + Dbx^2 + Day^2 + Dby^2 - (2 * Dax * Dbx) - (2 * Day * Dby)
b = (2 * Oax * Dax) - (2 * Oax * Dbx) - (2 * Obx * Dax) + (2 * Obx * Dbx)
+ (2 * Oay * Day) - (2 * Oay * Dby) - (2 * Oby * Day) + (2 * Oby * Dby)
c = Oax^2 + Obx^2 + Oay^2 + Oby^2
- (2 * Oax * Obx) - (2 * Oay * Oby) - (ra + rb)^2
t exists (collision will occur) if--
(a != 0) && (b^2 >= 4ac)
You can predict collision by using direction vector and speed, this gives you the next steps, and when they will make a collision (if there will be).
You just need to check line crossing algorithm to detect that...

Resources