Normalized uv for shaderModifiers .fragment attached to SCNGeometry (SCNPlane) - scenekit

seems quite difficult for me to get this info so I will ask here directly.
Q: How do I get the correct normalized UV when dealing with shaderModifiers .fragment attached to a geometry in a SCNNode?
More info:
SCNGeometry is SCNPlane and I want to make it half black, half white.
The below all return wrong positions
float2 uv = _surface.diffuseTexcoord
if ( uv.x > 0 ) { color = white;} else { color = black;}
float2 uv = _surface.diffuseTexcoord
if ( uv.x > 0.5 ) { color = white;} else { color = black;}
float2 uv = -1.0+2.0*_surface.diffuseTexcoord;
if ( uv.x > 0 ) { color = white;} else { color = black;}
float2 uv = _surface.diffuseTexcoord;
if ( uv.x > scn_node.boundingBox[0].x && uv.x < (scn_node.boundingBox[1].x / 2 ) ) { color = white;} else { color = black;}
float2 uv = -1.0+2.0*_surface.diffuseTexcoord;
if ( uv.x > scn_node.boundingBox[0].x && uv.x < (scn_node.boundingBox[1].x / 2 ) ) { color = white;} else { color = black;}
EDIT:
"How you are using the color variable?"
_output.color = color;
UPDATE:
Removing
myMaterial.diffuse.contentsTransform = SCNMatrix4MakeScale(value1, value2 , 1)
did the trick.
Applying 1/value1 and 1/value2 to uv will bring me back to the normalized value?
Also what is the normalized value for us in shaderModifiers? -1/+1 or 0/+1 ?

How are you using the color variable?
Here's a working example:
_output.color.rgb = step(_surface.diffuseTexcoord.x, 0.5);

Posting the answer to this question.
Hope will save time for the readers.
Q: How do I get the correct normalized UV when dealing with shaderModifiers .fragment attached to a geometry in a SCNNode?
A:
Usually x range is 0 <-> 1
Usually y range is 0 <-> 1
When you use SCNMatrix4MakeScale(Xvalue, Yvalue, Zvalue) on the node you have:
x range is 0 <-> Xvalue
y range is 0 <-> Yvalue

Related

How to get an alert once on a trend on a supertrend, in pinescript,with loop or another way?

How to get an alert once on a supertrend trend,I think with while i can solve(but my knowledge is not enough),maybe is another way to solve my problem.
I need to skip the first signal(on down/up trend) and enter the second alert, and this signal alert one time per supertrend trend.
I describe signals below in the code.
//#version=5
indicator("My-Supertrend", overlay=true, timeframe="", timeframe_gaps=true)
atrPeriod = input(13, "ATR Length")
atrPeriod2 = input(21, "ATR Length2")
factor = input.float(3.0, "Factor", step = 0.01)
factor2 = input.float(7.0, "Factor2", step = 0.01)
[supertrend, direction] = ta.supertrend(factor, atrPeriod)
[supertrend2, direction2] = ta.supertrend(factor2, atrPeriod2)
//ST 1
bodyMiddle = plot((open + close) / 2, display=display.none)
upTrend = plot(direction < 0 ? supertrend : na, "Up Trend", color = #00cf42, style=plot.style_linebr,linewidth=1)
downTrend = plot(direction < 0? na : supertrend, "Down Trend", color = #bb2c01, style=plot.style_linebr,linewidth=1)
//ST 2
bodyMiddle2 = plot((open + close) / 2, display=display.none)
upTrend2 = plot(direction2 < 0 ? supertrend2 : na, "Up Trend", color = #00cf42, style=plot.style_linebr,linewidth=3)
downTrend2 = plot(direction2 < 0? na : supertrend2, "Down Trend", color = #bb2c01, style=plot.style_linebr,linewidth=3)
//ST1 color
fill(bodyMiddle, upTrend, color.new(#95bd06, 80), fillgaps=false)
fill(bodyMiddle, downTrend, color.new(#0692bd, 80), fillgaps=false)
//ST2 color
fill(bodyMiddle2, upTrend2, color.new(#5abd13, 70), fillgaps=false)
fill(bodyMiddle2, downTrend2, color.new(#bd3006,70), fillgaps=false)
//Logic
down_upTrend=direction>0 and direction2<0 and direction[1]<0
up_upTrend=direction<0 and direction2<0 and direction[1]>0
up_downTrend=direction<0 and direction2>0 and direction[1]>0
down_downTrend=direction>0 and direction2>0 and direction[1]<0
//For short
while direction2>0
up_downTrend
continue
down_downTrend
break
//For Long
while direction2<0
down_upTrend
continue
up_upTrend
break
plotshape(up_upTrend,style=shape.triangleup,location=location.belowbar,size=size.normal,color=color.rgb(27, 182, 27))
plotshape(up_downTrend,style=shape.triangleup,location=location.belowbar,size=size.normal,color=color.rgb(20, 112, 20))
plotshape(down_upTrend,style=shape.triangledown,location=location.abovebar,size=size.normal,color=color.rgb(255, 0, 0))
plotshape(down_downTrend,style=shape.triangledown,location=location.abovebar,size=size.normal,color=color.rgb(141, 21, 21))
alertcondition(up_upTrend or down_downTrend,"Long/Short","Signal")
I try to solve with while loop(and i describe my logic in while loop),but while dont work like I think.

Map Layer Issues in ggplot2

I'm having a few issues with finalizing my map for a report. I think I'm warm on the solutions, but haven't quite figured them out. I would really appreciate any help on solutions so that I can finally move on!
1) The scale bar will NOT populate in the MainMap code and the subsequent Figure1 plot. This is "remedied" in the MainMap code if I comment out the "BCWA_land" map layer. However, when I retain the "BCWA_land" map layer it will eliminate the scale bar and produces this error:
Warning message: Removed 3 rows containing missing values (geom_text).
And this is the code:
MainMap <- ggplot(QOI) +
geom_sf(aes(fill = quadID)) +
scale_fill_manual(values = c("#6b8c42",
"#70b2ae",
"#d65a31")) +
labs(fill = "Quadrants of Interest",
caption = "Figure 1: Map depicting the quadrants in the WSDOT project area as well as other quadrants of interest in the Puget Sound area.")+
ggtitle("WSDOT Project Area and Quadrants of Interest") +
scalebar(x.min = -123, x.max = -122.8, y.min = 47, y.max = 47.1, location = "bottomleft",
transform = TRUE, dist = 10, dist_unit = "km", st.size = 3, st.bottom = TRUE, st.dist = 0.1) +
north(data = QOI, location = "topleft", scale = 0.1, symbol = 12, x.min = -123, y.min = 48.3, x.max = -122.7, y.max = 48.4) +
theme_bw()+
theme(panel.grid= element_line(color = "gray50"),
panel.background = element_blank(),
panel.ontop = TRUE,
legend.text = element_text(size = 11, margin = margin(l = 3), hjust = 0),
legend.position = c(0.95, 0.1),
legend.justification = c(0.85, 0.1),
legend.background = element_rect(colour = "#3c4245", fill = "#f4f4f3"),
axis.title = element_blank(),
plot.title = element_text(face = "bold", colour = "#3c4245", hjust = 0.5, margin = margin(b=10, unit = "pt")),
plot.caption = element_text(face = "italic", colour = "#3c4245", margin = margin(t = 7), hjust = 0, vjust = 0.5)) +
geom_sf(data = BCWA_land) + #this is what I've tried to comment out to determine the scale bar problem
xlim (-123.1, -121.4) +
ylim (47.0, 48.45)
MainMap
InsetRect <- data.frame(xmin=-123.2, xmax=-122.1, ymin=47.02, ymax=48.45)
InsetMap <- ggplotGrob( ggplot( quads) +
geom_sf(aes(fill = "")) +
scale_fill_manual(values = c("#eefbfb"))+
geom_sf(data = BCWA_land) +
scale_x_continuous(expand = c(0,0), limits = c(-124.5, -122.0)) +
scale_y_continuous(expand = c(0,0), limits = c(47.0, 49.5)) +
geom_rect(data = InsetRect,aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax),
color="#3c4245",
size=1.25,
fill=NA,
inherit.aes = FALSE) +
theme_bw()+
theme(legend.position = "none",
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
plot.margin = margin(0,0,0,0)))
InsetMap
Figure1 <- MainMap +
annotation_custom(grob = InsetMap, xmin = -122.2, xmax = -121.3,
ymin = 47.75, ymax = 48.5)
Figure1
As you can see I'm not getting this issue or error for my north arrow so I'm not really sure what is happening with the scale bar!
This problem is probably a little too OCD, however I REALLY don't want the gridlines to show up on the InsetMap, and was hoping that the InsetMap would overlay on top of the MainMap, without gridlines as I had those parameters set to element_blank() in the InsetMap code.
Here is an image of my plot. If you would like the data for this, please let me know. Because these are shapefiles, the data is unwieldy and not super conducive to SO's character limit for a post...
If anyone has any insight into a solution(s) I would so so appreciate that!! Thanks for your time!
The issue was the
xlim (-123.1, -121.4) +
ylim (47.0, 48.45)
call that I made. Instead, I used coord_sf(xlim = c(min, max), ylim = c(min, max)). I thought that this would be helpful to someone who might be in my position later on!
Essentially the difference between setting the limits of to the graph using just the x/y lim calls is that that truncates the data that is available in your dataset, whereas the coord_sf call simply "focuses" your graph on that extent if you will without altering the data you have available in your dataset.

Convert pinescript v2 to v4

I found 2 scripts in tradingview and added them to my script, however, it didn't work. I lost a lot of time. Can someone help me convert them to version 4? Thank you. Have a nice day!!!
//#version=2
////////////////////////////////////////////////////////////
// Copyright by HPotter v1.0 09/03/2018
// Linear Regression Intercept is one of the indicators calculated by using the
// Linear Regression technique. Linear regression indicates the value of the Y
// (generally the price) when the value of X (the time series) is 0. Linear
// Regression Intercept is used along with the Linear Regression Slope to create
// the Linear Regression Line. The Linear Regression Intercept along with the Slope
// creates the Regression line.
////////////////////////////////////////////////////////////
study(title="Line Regression Intercept", overlay = true)
Length = input(14, minval=1)
xSeria = input(title="Source", type=source, defval=close)
xX = Length * (Length - 1) * 0.5
xDivisor = xX * xX - Length * Length * (Length - 1) * (2 * Length - 1) / 6
xXY = 0
for i = 0 to Length-1
xXY := xXY + (i * xSeria[i])
xSlope = (Length * xXY - xX * sum(xSeria, Length)) / xDivisor
xLRI = (sum(xSeria, Length) - xSlope * xX) / Length
plot(xLRI, color=blue, title="LRI")
//Author - Rajandran R
//www.marketcalls.in
study("Supertrend V1.0 - Buy or Sell Signal", overlay = true)
Factor=input(3, minval=1,maxval = 100)
Pd=input(7, minval=1,maxval = 100)
Up=hl2-(Factor*atr(Pd))
Dn=hl2+(Factor*atr(Pd))
TrendUp=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn
Trend = close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl = Trend==1? TrendUp: TrendDown
linecolor = Trend == 1 ? green : red
plot(Tsl, color = linecolor , style = line , linewidth = 2,title = "SuperTrend")
plotshape(cross(close,Tsl) and close>Tsl , "Up Arrow", shape.triangleup,location.belowbar,green,0,0)
plotshape(cross(Tsl,close) and close<Tsl , "Down Arrow", shape.triangledown , location.abovebar, red,0,0)
//plot(Trend==1 and Trend[1]==-1,color = linecolor, style = circles, linewidth = 3,title="Trend")
plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=lime, maxheight=60, minheight=50, transp=0)
plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=red, maxheight=60, minheight=50, transp=0)
//#version=4
////////////////////////////////////////////////////////////
// Copyright by HPotter v1.0 09/03/2018
// Linear Regression Intercept is one of the indicators calculated by using the
// Linear Regression technique. Linear regression indicates the value of the Y
// (generally the price) when the value of X (the time series) is 0. Linear
// Regression Intercept is used along with the Linear Regression Slope to create
// the Linear Regression Line. The Linear Regression Intercept along with the Slope
// creates the Regression line.
////////////////////////////////////////////////////////////
study(title="Line Regression Intercept", overlay=true)
Length = input(14, minval=1)
xSeria = input(title="Source", type=input.source, defval=close)
xX = Length * (Length - 1) * 0.5
xDivisor = xX * xX - Length * Length * (Length - 1) * (2 * Length - 1) / 6
xXY = 0.
for i = 0 to Length - 1 by 1
xXY := xXY + i * xSeria[i]
xXY
xSlope = (Length * xXY - xX * sum(xSeria, Length)) / xDivisor
xLRI = (sum(xSeria, Length) - xSlope * xX) / Length
plot(xLRI, color=color.blue, title="LRI")
//#version=4
//Author - Rajandran R
//www.marketcalls.in
study("Supertrend V1.0 - Buy or Sell Signal", overlay=true)
Factor = input(3, minval=1, maxval=100)
Pd = input(7, minval=1, maxval=100)
Up = hl2 - Factor * atr(Pd)
Dn = hl2 + Factor * atr(Pd)
TrendUp = Up
TrendUp := close[1] > TrendUp[1] ? max(Up, TrendUp[1]) : Up
TrendDown = Dn
TrendDown := close[1] < TrendDown[1] ? min(Dn, TrendDown[1]) : Dn
Trend = int(na)
Trend := close > TrendDown[1] ? 1 : close < TrendUp[1] ? -1 : nz(Trend[1], 1)
Tsl = Trend == 1 ? TrendUp : TrendDown
linecolor = Trend == 1 ? color.green : color.red
plot(Tsl, color=linecolor, style=plot.style_line, linewidth=2, title="SuperTrend")
plotshape(cross(close, Tsl) and close > Tsl, "Up Arrow", shape.triangleup, location.belowbar, color.green, 0, 0)
plotshape(cross(Tsl, close) and close < Tsl, "Down Arrow", shape.triangledown, location.abovebar, color.red, 0, 0)
//plot(Trend==1 and Trend[1]==-1,color = linecolor, style = circles, linewidth = 3,title="Trend")
plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=color.lime, maxheight=60, minheight=50, transp=0)
plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=color.red, maxheight=60, minheight=50, transp=0)

Apache Solr heatmap : How to convert in usable coordinate int2d array returned by heatmap

I'm using faceting heatmap on a spatial field which then returns a 2d array like this
"counts_ints2D",
[
null,
null,
null,
null,
[
0,
8,
4,
0,
0,
0,
0,
0,
0,
...
I want to locate those cluster on the map but the problem is that I don't know how to convert that 2d array in geo coordinates.
There's absolutely no documentation out there showing what to do with those integer.
Can somebody give some guidance ?
Going with the data you gave for Glasgow, and using the formula given in the comments, lets explore the coordinates in a python repl:
# setup
>>> minX = -180
>>> maxX = 180
>>> minY = -53.4375
>>> maxY = 74.53125
>>> columns = 256
>>> rows = 91
# calculate widths
>>> bucket_width = (maxX - minX) / columns
>>> bucket_width
1.40625
>>> bucket_height = (maxY - minY) / rows
>>> bucket_height
1.40625
# calculate area for bucket in heatmap facet for x = 124, y = 13
# point in lower left coordinate
>>> lower_left = {
... 'lat': maxY - (13 + 1) * bucket_height,
... 'lon': minX + 124 * bucket_width,
... }
>>> lower_left
{'lat': 54.84375, 'lon': -5.625}
# point in upper right
>>> upper_right = {
... 'lat': maxY - (13 + 1) * bucket_height + bucket_height,
... 'lon': minX + 124 * bucket_width + bucket_width,
... }
>>> upper_right
{'lat': 56.25, 'lon': -4.21875}
Let's graph these points on a map, courtesy of open street map. We generate a small CSV snippet we can import on umap (select the up arrow, choose 'csv' as the type and enter content into the text box). To our coordinates to show:
>>> bbox = [
... "lat,lon,description",
... str(lower_left['lat']) + "," + str(lower_left['lon']) + ",ll",
... str(upper_right['lat']) + "," + str(lower_left['lon']) + ",ul",
... str(upper_right['lat']) + "," + str(upper_right['lon']) + ",uu",
... str(lower_left['lat']) + "," + str(upper_right['lon']) + ",lu",
... ]
>>> print("\n".join(bbox))
lat,lon,description
54.84375,-5.625,ll
56.25,-5.625,ul
56.25,-4.21875,uu
54.84375,-4.21875,lu
After pasting these points into the import box creating the layer, we get this map:
Map based on Open Street Map data through uMap. This area encloses Glasgow as you expected.
Here's some code that takes 180th meridian (date line) wrapping into account:
$columns = $heatmap['columns'];
$rows = $heatmap['rows'];
$minX = $heatmap['minX'];
$maxX = $heatmap['maxX'];
$minY = $heatmap['minY'];
$maxY = $heatmap['maxY'];
$counts = $heatmap['counts_ints2D'];
// If our min longitude is greater than max longitude, we're crossing
// the 180th meridian (date line).
$crosses_meridian = $minX > $maxX;
// Bucket width needs to be calculated differently when crossing the
// meridian since it wraps.
$bucket_width = $crosses_meridian
? $bucket_width = (360 - abs($maxX - $minX)) / $columns
: $bucket_width = ($maxX - $minX) / $columns;
$bucket_height = ($maxY - $minY) / $rows;
$points = [];
foreach ($counts as $rowIndex => $row) {
if (!$row) continue;
foreach ($row as $columnIndex => $column) {
if (!$column) continue;
$point = []
$point['count'] = $column;
// Put the count in the middle of the bucket (adding a half height and width).
$point['lat'] = $maxY - (($rowIndex + 1) * $bucket_height) + ($bucket_height / 2);
$point['lng'] = $minX + ($columnIndex * $bucket_width) + ($bucket_width / 2);
// We crossed the meridian, so wrap back around to negative.
if ($point['lng'] > 180) {
$point['lng'] = -1 * (180 - ($point['lng'] % 180));
}
$points[] = $point;
}
}

Create bounding box from center coordinate

I'm trying to create a bounding box at a specific scale from a center coordinate. I'm trying to keep it within the aspect ratio of a 8.5x11inch piece of paper (612x792 pixels # 72dpi).
The code I'm using below mostly works, but the heigh seems a bit too tall for the aspect ratio of a letter. Am I not accounting for mercator projection? What am I missing here?
def bounding_box_from_point(center:, size:, scale_denominator:)
dpi = 72
inches_per_unit = 4374754
resolution = 1 / (scale_denominator * inches_per_unit * dpi)
half_width_deg = (size.width * resolution) / 2
half_height_deg = (size.height * resolution) / 2
BoundingBox.new(
north: center.lat + half_height_deg,
south: center.lat - half_height_deg,
east: center.lon + half_width_deg,
west: center.lon - half_width_deg
)
end
Calling bounding_box_from_point(center: center, size: size, scale_denominator: scale) with:
scale = 0.0008861342166177423 (i.e. 1/18055.955520)
center = Geometry::Location.new(lat: 37.806336, lon: -122.270625)
size.width = 612,
size.height = 792
It returns:
west: -122.27172131608657,
east: -122.26952868391342,
south: 37.804917238005615
north: 37.80775476199439
If you go to http://www.openstreetmap.org/export and enter those bounding box coordinates, you can see that the ratio does not match that of a 8.5x11in piece of paper...it's slightly too tall. What am I doing wrong here or not understanding?
This was my implementation that solved it!
def self.bounding_box_from_location(location:, scale:)
scale_meters_per_pixel = 0.0003
# scale.zoom is an integer between 0-19
# See http://wiki.openstreetmap.org/wiki/Zoom_levels for a description on `zoom`
# location.lat_rad is the latitude in radians, same for lon_rad
meters_per_pixel = EARTH_CIR * Math.cos(location.lat_rad) / (2 ** (scale.zoom + 8))
earth_meters_per_pictureMeters = meters_per_pixel / scale_meters_per_pixel
# height/width in meters is the height/width of the box you're applying this to
# In my case I'm using the heigh/width of a Letter of paper
# You can convert Pixels to meters (# 72dpi) with
# pixels * 0.00035277777777777776
meters_north = earth_meters_per_pictureMeters * scale.height_in_meters / 2
meters_east = earth_meters_per_pictureMeters * scale.width_in_meters / 2
meters_per_degree_lat = 111111.0
meters_per_degree_long = 111111.0 * Math.cos(location.lat_rad)
degrees_north = meters_north / meters_per_degree_lat
degrees_east = meters_east / meters_per_degree_long
BoundingBox.new(
north: (location.lat + degrees_north),
south: location.lat - degrees_north,
east: location.lon + degrees_east,
west: location.lon - degrees_east,
width: scale.width_in_pixels,
height: scale.height_in_pixels
)
end

Resources