hit.getDistance() not giving proper distance - arcore

I am looking to measure the height of a HitPose in ARcore and I am finding that the function getDistance sometimes returns what seems to be the wrong value for planes.
Any thoughts on why this is or how to know how getDistance is calculating it's value?
I am using the handleTap function in the HelloArActivity.java(https://github.com/google-ar/arcore-android-sdk) to demonstrate this.
I added the following function to dump the hit results of a hit test and call it in handleTap. Sample output shows the distance is intermittently way off yet calculating the distance but the sample function calculateDistanceToPlane shows the correct distance. Sample output follows code
private String DumpHitList(List<HitResult> hitResultList, Frame frame){
String str = new String();
double angle[] = getAngleofthedevice();
int index = 0;
str = ".......Hit list size:"+hitResultList.size()+"..";
for (HitResult hit : hitResultList){
Trackable trackable = hit.getTrackable();
// stuff to dump
str += "\n[hit"+index++ +":";
if (trackable instanceof Plane){
str += "PLANE," + ((Plane) trackable).getType().toString()
+",inPolyGon:"+((Plane) trackable).isPoseInPolygon(hit.getHitPose())
+",normdist:" + PlaneRenderer.calculateDistanceToPlane(hit.getHitPose(), frame.getCamera().getPose())
;
}
else if (trackable instanceof Point) {
str += "POINT," +((Point) trackable).getOrientationMode()
+",adjDist:"+ hit.getDistance()
* (float)( Math.cos(Math.toRadians(angle[1])) * Math.cos(Math.toRadians(angle[2])))
;
}
else{
str+= "OTHER TRACKABLE TYPE";
}
str += " trackDist:" + hit.getDistance() + " state:" + hit.getTrackable().getTrackingState();
//str += ",hitXYZ:" + hit.getHitPose().tx() +","+hit.getHitPose().ty() +","+hit.getHitPose().tz()
str += "\nhitPose:" + hit.getHitPose().toString();
str += ",\ncamPose:" + frame.getCamera().getPose().toString()
+"]\n ";
}
str +="........";
return str;
}
Sample output (note the "trackdist" is way off from the norm distance).
2020-01-27 14:43:16.285 23970-24023/? D/Ahab: in create colored anchor plane:HORIZONTAL_UPWARD_FACING hit dist:0.13333696, anchorDist: 0.23327702, hitlist size:1.......Hit list size:1..
[hit0:PLANE,HORIZONTAL_UPWARD_FACING,inPolyGon:true,normdist:0.23327702 trackDist:0.13333696 state:TRACKING
hitPose:t:[x:0.167, y:-0.783, z:-0.821], q:[x:0.00, y:-0.59, z:-0.00, w:0.81],
camPose:t:[x:0.161, y:-0.549, z:-0.819], q:[x:0.43, y:0.56, z:0.56, w:-0.44]]
........
2020-01-27 14:43:21.326 23970-24023/? D/Ahab: in create colored anchor pt:ESTIMATED_SURFACE_NORMAL hit dist:0.2452918, anchorDist: 0.24518394, hitlist size:2.......Hit list size:2..
[hit0:POINT,ESTIMATED_SURFACE_NORMAL,adjDist:0.24518394 trackDist:0.2452918 state:TRACKING
hitPose:t:[x:-0.091, y:-0.792, z:-0.789], q:[x:0.00, y:0.62, z:0.01, w:0.78],
camPose:t:[x:-0.095, y:-0.547, z:-0.789], q:[x:0.53, y:0.46, z:0.46, w:-0.54]]
[hit1:PLANE,HORIZONTAL_UPWARD_FACING,inPolyGon:true,normdist:0.2366659 trackDist:0.13668406 state:TRACKING
hitPose:t:[x:-0.091, y:-0.783, z:-0.789], q:[x:0.00, y:-0.64, z:-0.00, w:0.77],
camPose:t:[x:-0.095, y:-0.547, z:-0.789], q:[x:0.53, y:0.46, z:0.46, w:-0.54]]
=====more sample output notice in one dump, "trackdist" is accurate but next dump, it is wrong.
2020-01-27 14:43:16.285 23970-24023/? D/Ahab: in create colored anchor plane:HORIZONTAL_UPWARD_FACING hit dist:0.13333696, anchorDist: 0.23327702, hitlist size:1.......Hit list size:1..
[hit0:PLANE,HORIZONTAL_UPWARD_FACING,inPolyGon:true,normdist:0.23327702 trackDist:0.13333696 state:TRACKING
hitPose:t:[x:0.167, y:-0.783, z:-0.821], q:[x:0.00, y:-0.59, z:-0.00, w:0.81],
camPose:t:[x:0.161, y:-0.549, z:-0.819], q:[x:0.43, y:0.56, z:0.56, w:-0.44]]
........
2020-01-27 14:43:21.326 23970-24023/? D/Ahab: in create colored anchor pt:ESTIMATED_SURFACE_NORMAL hit dist:0.2452918, anchorDist: 0.24518394, hitlist size:2.......Hit list size:2..
[hit0:POINT,ESTIMATED_SURFACE_NORMAL,adjDist:0.24518394 trackDist:0.2452918 state:TRACKING
hitPose:t:[x:-0.091, y:-0.792, z:-0.789], q:[x:0.00, y:0.62, z:0.01, w:0.78],
camPose:t:[x:-0.095, y:-0.547, z:-0.789], q:[x:0.53, y:0.46, z:0.46, w:-0.54]]
[hit1:PLANE,HORIZONTAL_UPWARD_FACING,inPolyGon:true,normdist:0.2366659 trackDist:0.13668406 state:TRACKING
hitPose:t:[x:-0.091, y:-0.783, z:-0.789], q:[x:0.00, y:-0.64, z:-0.00, w:0.77],
camPose:t:[x:-0.095, y:-0.547, z:-0.789], q:[x:0.53, y:0.46, z:0.46, w:-0.54]]

Related

How can I create a textbox class in love2d that can input data to calculate?

How can I make a text box to be able to enter numbers using them to calculate in love2d ?
steps:
(optional) capture mouse / touch location
store input, in a string variable
sanitize input, make sure there aren't unexpected chars
calculate results, use load(str) then execute that ()
print results
Capturing mouse is optional, only required if your app has more than one function. If it's a single-use app that only calculates what you type in, there's no need for that first step. However, if there are other selectable locations on the screen, you'll need a way to determine that the user desires that input area. There are a few GUI libs that help with this, or you can simply test if it's within the expected screen x,y region.
function love.load()
fontsize = 16
fontname = "font.ttf"
font = love.graphics.newFont( fontname, fontsize )
input_x_min = 20
input_x_max = 400
input_y_min = 20
input_y_max = input_y_min +fontsize *2
allowed_chars = "1234567890()+-*/"
love.keyboard.setTextInput( false )
input_text = "result=" -- for storing input
result = nil -- empty placeholder for now
output_x = 20
output_y = 40
output_limit = 400
end
function love.update(dt)
local x, y = love.mouse.getPosition()
-- could also capture mouseclicks here, and/or get touch events
if x >= input_x_min and x <= input_x_max
and y >= input_y_min and y <= input_y_max then
love.keyboard.setTextInput( true )
else
love.keyboard.setTextInput( false )
input_text = "result=" -- no longer selected, reset input
end
end
function love.textinput(t)
for i = 1, #allowed_chars do -- sanitize input
if allowed_chars :sub(i,i) == t then -- if char is allowed
input_text = input_text ..t -- append what was typed
generate_result, err = load( input_text ) -- "result=3+(2*2)"
if err then print( err )
else generate_result() -- function() return result=3+(2*2) end
end
end
end
end
function love.draw()
love.graphics.printf( input_text, output_x, output_y, input_limit )
love.graphics.printf( result, output_x, output_y, output_limit )
end

Trying to make function which takes string as input and returns no. of words in whole string

**It takes Input as a string such as this - 'Nice one'
And Output gives - 4,3 (which is no. Of words in sentence or string)
**
function countx(str)
local count = {}
for i = 1, string.len(str) do
s = ''
while (i<=string.len(str) and string.sub(str, i, i) ~= ' ' ) do
s = s .. string.sub(str, i, i)
i = i+1
end
if (string.len(s)>0) then
table.insert(count,string.len(s))
end
end
return table.concat(count, ',')
end
You can find a simple alternative with your new requirements:
function CountWordLength (String)
local Results = { }
local Continue = true
local Position = 1
local SpacePosition
while Continue do
SpacePosition = string.find(String, " ", Position)
if SpacePosition then
Results[#Results + 1] = SpacePosition - Position
Position = SpacePosition + 1
-- if needed to print the string
-- local SubString = String:sub(Position, SpacePosition)
-- print(SubString)
else
Continue = false
end
end
Results[#Results + 1] = #String - Position + 1
return Results
end
Results = CountWordLength('I am a boy')
for Index, Value in ipairs(Results) do
print(Value)
end
Which gives the following results:
1
2
1
3
def countLenWords(s):
s=s.split(" ")
s=map(len,s)
s=map(str,s)
s=list(s)
return s
The above functions returns a list containing number of characters in each word
s=s.split(" ") splits string with delimiter " " (space)
s=map(len,s) maps the words into length of the words in int
s=map(str,s) maps the values into string
s=list(s) converts map object to list
Short version of above function (all in one line)
def countLenWords(s):
return list(map(str,map(len,s.split(" "))))
-- Localise for performance.
local insert = table.insert
local text = 'I am a poor boy straight. I do not need sympathy'
local function word_lengths (text)
local lengths = {}
for word in text:gmatch '[%l%u]+' do
insert (lengths, word:len())
end
return lengths
end
print ('{' .. table.concat (word_lengths (text), ', ') .. '}')
gmatch returns an iterator over matches of a pattern in a string.
[%l%u]+ is a Lua regular expression (see http://lua-users.org/wiki/PatternsTutorial) matching at least one lowercase or uppercase letter:
[] is a character class: a set of characters. It matches anything inside brackets, e.g. [ab] will match both a and b,
%l is any lowercase Latin letter,
%u is any uppercase Latin letter,
+ means one or more repeats.
Therefore, text:gmatch '[%l%u]+' will return an iterator that will produce words, consisting of Latin letters, one by one, until text is over. This iterator is used in generic for (see https://www.lua.org/pil/4.3.5.html); and on any iteration word will contain a full match of the regular expression.

How to notify a number increase & decrease in MQL4 code?

can anyone help me, how to write MQL4 code to know if the result is increase OR decrease..
Example:
if a result was first 0.0543 and then it is increased to 0.1342 and later decreased to 0.10345, I want to implement it to my code below:
int start()
{
double val = iCustom( NULL, 0, "SS2009_B", 0, 0, 0 );
ObjectSet( "TimeLable11", OBJPROP_CORNER, obCorner );
ObjectSetText( "TimeLable11", "Result : " + val,
fsize,
"Microsoft Sans Serif",
Yellow
);
return( 0 );
}
I want the result to have an increasing OR a decreasing notification.
Example :
Result : 0.1849 Increasing
Result : 0.01324 Decreasing
To have a SIMPLE example:
//------------------------------------------------------------------
#property copyright "Copyright 2015"
//------------------------------------------------------------------
// Standard Variables (define a variable to store previous value)
//------------------------------------------------------------------
double viIndicatorValuePrev = 0.0000;
int start() {
double viIndicatorValueNow = iCustom(NULL,0,"SS2009_B",0,0,0);
//------------------------------------------------
//Decide on direction (increasing or decreasing)
//------------------------------------------------
string vsDirection = "Same";
if( viIndicatorValueNow>viIndicatorValuePrev)
vsDirection = "Increasing";
if( viIndicatorValueNow<viIndicatorValuePrev)
vsDirection = "Decreasing";
//------------------------------------------------
//------------------------------------------------
// Do your thing here (ie, display stuff)
//------------------------------------------------
ObjectSet( "TimeLable11", OBJPROP_CORNER, obCorner);
ObjectSetText(
"TimeLable11"
, "Result : " + viIndicatorValueNow + " (" + vsDirection + ")"
, fsize, "Microsoft Sans Serif", Yellow
);
//------------------------------------------------
// Store current value for future comparison
//------------------------------------------------
viIndicatorValuePrev = viIndicatorValueNow;
//------------------------------------------------
return(0);
}
Hope this example helps.
Solution to monitor & show delta per each aMarketEVENT call of start() ( upon aMarketQUOTE aka Tick arrival )
First you need a method to store and retain a value, that becomes "old", in the meantime, before the start() ( well actually an OnTick() in the new-MQL century ) is called next time.
A static double is a smart way to go:
static double previousVALUE = EMPTY; // initialised to EMPTY
Next, initialise it in accord with a forward-stepping logic of the Custom Indicator "SS2009_B"
if ( previousVALUE == EMPTY ) {
previousVALUE = iCustom( NULL, // a Symbol
0, // a TimeFRAME
"SS2009_B",
0,
0, // a Buffer# to get value from
1 // step-back one Bar
);
}
For syntax details, review MQL4 documentation
double iCustom(
string symbol, // symbol
int timeframe, // timeframe
string name, // path/name of the custom indicator compiled program
... // custom indicator input parameterA (if
... // custom indicator input parameterB (if
... // custom indicator input parameterC (if necessary)
int mode, // line index
int shift // shift
);
Finally calculate delta & show it on UI & shuffle to get ready for a next call
double currentVALUE = iCustom( NULL, 0, "SS2009_B", 0, 0, 0);
double deltaVALUE = previousVALUE - currentVALUE;
previousVALUE = currentVALUE; // shuffle [1]<-[0] before RET/next call
if ( deltaVALUE > 0 ){
ObjectSetText( "TimeLabel11",
"RESULT: " + NormalizeDouble( deltaVALUE, Digits ) + "|^|",
fsize,
"Courier New",
Yellow // can be deltaVALUE specific too :o)
);
}
if ( deltaVALUE < 0 ){
ObjectSetText( "TimeLabel11",
"RESULT: " + NormalizeDouble( deltaVALUE, Digits ) + "|v|",
fsize,
"Courier New",
Cyan // can be deltaVALUE specific too :o)
);
}
A few remarks on precision of float numbers
You may notice a use of NormalizeDouble()
This is rather important step, to avoid problems with comparison of floats.
If the precision of standard floats ( MQL4 double ) is not sufficient, you may opt-in to use extended precision numbers in MQL4. Check documentation for that.
However, always be carefull on float comparisons.
Best practice, to be on a safer side, is to use both NormalizeDouble() ( as a prevention )
and
comparing to some thresholdDELTA like if ( MathAbs( floatA - floatB ) < anEqualityTresholdDELTA ){ ... } rather than if ( floatA == floatB ) {...}

LPeg Increment for Each Match

I'm making a serialization library for Lua, and I'm using LPeg to parse the string. I've got K/V pairs working (with the key explicitly named), but now I'm going to add auto-indexing.
It'll work like so:
#"value"
#"value2"
Will evaluate to
{
[1] = "value"
[2] = "value2"
}
I've already got the value matching working (strings, tables, numbers, and Booleans all work perfectly), so I don't need help with that; what I'm looking for is the indexing. For each match of #[value pattern], it should capture the number of #[value pattern]'s found - in other words, I can match a sequence of values ("#"value1" #"value2") but I don't know how to assign them indexes according to the number of matches. If that's not clear enough, just comment and I'll attempt to explain it better.
Here's something of what my current pattern looks like (using compressed notation):
local process = {} -- Process a captured value
process.number = tonumber
process.string = function(s) return s:sub(2, -2) end -- Strip of opening and closing tags
process.boolean = function(s) if s == "true" then return true else return false end
number = [decimal number, scientific notation] / process.number
string = [double or single quoted string, supports escaped quotation characters] / process.string
boolean = P("true") + "false" / process.boolean
table = [balanced brackets] / [parse the table]
type = number + string + boolean + table
at_notation = (P("#") * whitespace * type) / [creates a table that includes the key and value]
As you can see in the last line of code, I've got a function that does this:
k,v matched in the pattern
-- turns into --
{k, v}
-- which is then added into an "entry table" (I loop through it and add it into the return table)
Based on what you've described so far, you should be able to accomplish this using a simple capture and table capture.
Here's a simplified example I knocked up to illustrate:
lpeg = require 'lpeg'
l = lpeg.locale(lpeg)
whitesp = l.space ^ 0
bool_val = (l.P "true" + "false") / function (s) return s == "true" end
num_val = l.digit ^ 1 / tonumber
string_val = '"' * l.C(l.alnum ^ 1) * '"'
val = bool_val + num_val + string_val
at_notation = l.Ct( (l.P "#" * whitesp * val * whitesp) ^ 0 )
local testdata = [[
#"value1"
#42
# "value2"
#true
]]
local res = l.match(at_notation, testdata)
The match returns a table containing the contents:
{
[1] = "value1",
[2] = 42,
[3] = "value2",
[4] = true
}

Detailed distance between words

How would I go about displaying detailed distance between words.
For example, the output of the program could be:
Words are "car" and "cure":
Replace "a" with "u".
Add "e".
The Levenshtein distance does not fulfill my needs (I think).
Try the following. The algorithm is roughly following Wikipedia (Levenshtein distance). The language used below is ruby
Use as an example, the case of changing s into t as follows:
s = 'Sunday'
t = 'Saturday'
First, s and t are turned into arrays, and an empty string is inserted at the beginning. m will eventually be the matrix used in the argorithm.
s = ['', *s.split('')]
t = ['', *t.split('')]
m = Array.new(s.length){[]}
m here, however, is different from the matrix given if the algorithm in wikipedia for the fact that each cell includes not only the Levenshtein distance, but also the (non-)operation (starting, doing nothing, deletion, insertion, or substitution) that was used to get to that cell from an adjacent (left, up, or upper-left) cell. It may also include a string describing the parameters of the operation. That is, the format of each cell is:
[Levenshtein distance, operation(, string)]
Here is the main routine. It fills in the cells of m following the algorithm:
s.each_with_index{|a, i| t.each_with_index{|b, j|
m[i][j] =
if i.zero?
[j, "started"]
elsif j.zero?
[i, "started"]
elsif a == b
[m[i-1][j-1][0], "did nothing"]
else
del, ins, subs = m[i-1][j][0], m[i][j-1][0], m[i-1][j-1][0]
case [del, ins, subs].min
when del
[del+1, "deleted", "'#{a}' at position #{i-1}"]
when ins
[ins+1, "inserted", "'#{b}' at position #{j-1}"]
when subs
[subs+1, "substituted", "'#{a}' at position #{i-1} with '#{b}'"]
end
end
}}
Now, we set i, j to the bottom-right corner of m and follow the steps backwards as we unshift the contents of the cell into an array called steps, until we reach the start.
i, j = s.length-1, t.length-1
steps = []
loop do
case m[i][j][1]
when "started"
break
when "did nothing", "substituted"
steps.unshift(m[i-=1][j-=1])
when "deleted"
steps.unshift(m[i-=1][j])
when "inserted"
steps.unshift(m[i][j-=1])
end
end
Then we print the operation and the string of each step unless that is a non-operation.
steps.each do |d, op, str=''|
puts "#{op} #{str}" unless op == "did nothing" or op == "started"
end
With this particular example, it will output:
inserted 'a' at position 1
inserted 't' at position 2
substituted 'n' at position 2 with 'r'
class Solution:
def solve(self, text, word0, word1):
word_list = text.split()
ans = len(word_list)
L = None
for R in range(len(word_list)):
if word_list[R] == word0 or word_list[R] == word1:
if L is not None and word_list[R] != word_list[L]:
ans = min(ans, R - L - 1)
L = R
return -1 if ans == len(word_list) else ans
ob = Solution()
text = "cat dog abcd dog cat cat abcd dog wxyz"
word0 = "abcd"
word1 = "wxyz"
print(ob.solve(text, word0, word1))

Resources