My problem is to know whether or not a point is contained in a polygon (sets of points) on the same surface.
Simple example in my favorite language DART
Point myPoint = new Point(10, 12);
List<Point> myPolygon = [ // The Polygon, for example is simple rect
new Point(2, 7),
new Point(15,7),
new Point(15, 18),
new Point(2, 18)
];
bool pointIsContainedInPolygon(List Polygon){
// .. data processing ...
}
I need to know what is the function: pointIsContainedInPolygon(myPolygon)
I have resumed the code data in the How can I determine whether a 2D Point is within a Polygon? post in dart, here is the result (tested)
bool pnpoly(Point point, List<Point> polygon){
// Step 1: Cut and detail
int nvert = polygon.length;
List<int> vertx = [];
List<int> verty = [];
for(Point vert in polygon){ // Listing x and y pos of all vertices
vertx.add(vert.x);
verty.add(vert.y);
}
// Step 2: Calcul..
bool c = false;
int j = nvert-1;
for (int i = 0; i < nvert; j = i++){
if( ((verty[i]>point.y) != (verty[j]>point.y)) && (point.x < (vertx[j]-vertx[i]) * (point.y-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ){
c = !c;
}
}
return c;
}
Here is my test
List<Point> myPolygon = [ // classic rectangle
new Point(2,2),
new Point(52,2),
new Point(52,41),
new Point(2,41)
];
Point myPoint = new Point(53,40);
print( pnpoly(myPoint, myPolygon) ); // false
Related
Hi im tryign to create a zigzag path using Path.js's onMouseDrag function but getting in to a bit of a muddle here is a sketch
and code
var path
var zigzag
var length
var count
var delta=[]
tool.fixedDistance= 20
function onMouseDown(event){
path= new Path()
path.add(event.point)
zigzag= new Path()
}
function onMouseDrag(event){
event.delta += 90
path.add(event.delta)
delta.push(event.delta)
}
function onMouseUp(event){
length= path.segments.length
zigzag= new Path()
zigzag.add(event.point)
console.log(delta)
delta.forEach(( zig , i) => {
zigzag.add(i % 2 == 0 ? zig + 20 : zig - 20)
})
zigzag.selected= true
}
Based on my previous answer, here is a sketch demonstrating a possible way to do it.
let line;
let zigZag;
function onMouseDown(event) {
line = new Path({
segments: [event.point, event.point],
strokeColor: 'black'
});
zigZag = createZigZagFromLine(line);
}
function onMouseDrag(event) {
line.lastSegment.point = event.point;
if (zigZag) {
zigZag.remove();
}
zigZag = createZigZagFromLine(line);
}
function createZigZagFromLine(line) {
const zigZag = new Path({ selected: true });
const count = 20, length = line.length;
for (let i = 0; i <= count; i++) {
const offset = i / count * length;
const normal = i === 0 || i === count
? new Point(0, 0)
: line.getNormalAt(offset) * 30;
const point = line.getPointAt(offset).add(i % 2 == 0 ? normal
: -normal);
zigZag.add(point);
}
return zigZag;
}
enter image description hereWe are trying to convert lzw compressed raster(tiff) into text format(meaning extracting each pixel centroid and band1 value.. We see that some parts of the raster is missed while conversion.. however there is a pattern in miss data (data is coming in unequal striped pattern) Please see snapshot up .. Yellow dots shows the centroid converted while no overlap with yellow the data is missed while converting..
we have tried the tile size 128 and 256 but the output was different in both the cases
List<String> tiffExtensions = new ArrayList<>();
tiffExtensions.add(".tif");
tiffExtensions.add(".TIF");
tiffExtensions.add(".tiff");
tiffExtensions.add(".TIFF");
final scala.Option<CRS> crsNone = scala.Option.apply(null);
final scala.Option<Object> objectNone = scala.Option.apply(null);
final scala.Option<Object> numPartitionsObject = scala.Option.apply(new Integer(10));
final scala.Option<Object> tileSize = scala.Option.apply(Integer.parseInt("256"));
final scala.Option<Object> partitionBytes = scala.Option.apply(128l * 1024 * 1024);
HadoopGeoTiffRDD.Options options = new HadoopGeoTiffRDD.Options$().apply(
JavaConverters.asScalaIteratorConverter(tiffExtensions.iterator()).asScala().toSeq(), crsNone,
HadoopGeoTiffRDD.GEOTIFF_TIME_TAG_DEFAULT(), HadoopGeoTiffRDD.GEOTIFF_TIME_FORMAT_DEFAULT(), tileSize,
numPartitionsObject, partitionBytes, objectNone);
RDD<Tuple2<ProjectedExtent, Tile>> rasterImageRdd = HadoopGeoTiffRDD.spatial(new Path(rastedImageDir), options,
javaSparkContext.sc());
JavaRDD<Tuple2<ProjectedExtent, Tile>> rasterImageJavaRdd = rasterImageRdd.toJavaRDD();
JavaRDD<String> pixelRdd = rasterImageJavaRdd
.flatMap(new FlatMapFunction<Tuple2<ProjectedExtent, Tile>, String>() {
private static final long serialVersionUID = -6395159549445351446L;
public Iterator<String> call(Tuple2<ProjectedExtent, Tile> v1) throws Exception {
ArrayList<String> list = new ArrayList<String>();
Tile t = v1._2;
ProjectedExtent projectedExtent = v1._1;
ProjectedRaster<CellGrid> r = new ProjectedRaster<CellGrid>(
new Raster<CellGrid>(t, projectedExtent.extent()), projectedExtent.crs());
GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4283);
WKTWriter wktWriter = new WKTWriter();
for (int i = 0; i < t.rows(); i++) {
for (int j = 0; j < t.cols(); j++) {
StringBuilder sb = new StringBuilder();
if (!Double.isNaN(t.getDouble(j, i))) {
Double elevation = t.getDouble(j, i);
Tuple2<Object, Object> longLatTupel = r.raster().rasterExtent().gridToMap(j, i);
if (longLatTupel._2() != null && longLatTupel._1() != null) {
Double latitude = Double.parseDouble(longLatTupel._2() + "");
Double longitude = Double.parseDouble(longLatTupel._1() + "");
Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
sb.append(elevation).append(TAB_SEP);
sb.append(point);
list.add(sb.toString());
}
}
}
}
return list.iterator();
}
});
_
I'm trying to retrieve the Points of a SignaturePad to redisplay the signature.
public static void GetPoints(string airid, SignaturePadView padView)
{
List<Strokes> DBStrokes = SqLiteHelper.conn.Query<Strokes>("select * from Strokes where airid = ? order by PointSequence", airid);
List<Point> points = new List<Point>();
foreach (Strokes stroke in DBStrokes)
points.Add(new Point { X = stroke.pointx, Y = stroke.pointy });
padView.Points = points.AsEnumerable();
}
The array points is filled correctly, but the padView.Points shows as result
{Xamarin.Forms.Point[0]}.
I've found the Problem. It seems that it is only possible to set the Points property when the Signaturepad is visible. so my new code looks like this:
List<Strokes> DBStrokes = SqLiteHelper.conn.Query<Strokes>("select * from Strokes where airid = ? order by PointSequence", formField.pictFile);
Xamarin.Forms.Point[] points = new Point[DBStrokes.Count];
for (int i = 0; i < DBStrokes.Count; i++)
points[i] = new Point(DBStrokes[i].pointx, DBStrokes[i].pointy);
var originalPoints = JsonConvert.SerializeObject(points);
Xamarin.Forms.Point[] points4View = JsonConvert.DeserializeObject<Xamarin.Forms.Point[]>(originalPoints);
signatureView.Points = points4View;
Now i'm using the Handle_MeasureInvalidated - Event to run this code.
I have a list of Vectors which represent points on three different floors in three.js.
I am trying to group these vectors according to the floor they belong to. Is there a good formula to do this? Perhaps find height from on vector or something. Not sure how to go about this. Any help would be appreciated.
Thanks,
Rob
As Wilt said... Can't really help you without more info.
Still, if your floors are even and all stand on the xz plane (in my example), You may indeed check the points' height (position.y) against the floors'.
var container, renderer, scene, camera, controls;
var floors = [];
var points = [], materials = [], heights = [];
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.createElement('div');
document.body.appendChild(container);
container.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
// camera + controls
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 50, 750);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;
//floors
for(i=0; i<3; i++) {
var planeGeometry = new THREE.BoxGeometry(500, 500, 10, 10);
var planeMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff * Math.random(),
side: THREE.DoubleSide,
transparent: true,
opacity : 0.3,
depthWrite : false //get rid of coplanar glitches wall/floor
});
materials.push(planeMaterial);
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = Math.PI / 2;
//plane.rotation.y = Math.PI / 8; //Uncomment to see this doesn't work if the floors move, i.e. changing rotation/position. If this is what you need, just raycast from point to floor in the animation loop and count how many floors the ray goes through (intersects.length)
plane.position.y = 75*i;
heights.push(plane.position.y);
floors.push(plane);
scene.add(plane);
}
//wall
var height = heights[2];
var planeGeometry = new THREE.BoxGeometry(500, height+100, 10, 10);
var planeMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff * Math.random(),
side: THREE.DoubleSide,
transparent: true,
opacity:0.3,
depthWrite : false //get rid of coplanar glitches wall/floor
});
materials.push(planeMaterial);
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.y = heights[1]+45;
plane.position.z = -510/2;
scene.add(plane);
// points
for (i=0; i<200; i++) {
var sphereGeometry = new THREE.SphereGeometry(3, 32, 16);
var sphere = new THREE.Mesh(sphereGeometry);
sphere.position.x = Math.random() * 500 - 250;
sphere.position.y = Math.random() * 300 - 100;
sphere.position.z = Math.random() * 500 - 250;
scene.add(sphere);
points.push(sphere);
}
// events
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize(event) {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function addSpheres() {
//addSpheres
for (i=0;i<200;i++) {
var that = points[i].position.y;
points[i].position.y = ( that < heights[0] ) ? 200 : that - 0.5;
if ( that > heights[0] && that < heights[1] ) points[i].material = materials[0];
if ( that < heights[2] && that > heights[1] ) points[i].material = materials[1];
if ( that > heights[2] ) points[i].material = materials[2];
points[i].material.needsUpdate = true;
}
}
function animate() {
controls.update();
addSpheres();
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
Now, feel free to "group" these points according to your needs.
Please note that "vectors" are different from "points". Read more about the difference.
Raycasting would be the way to go if you had a more complex scene (moving floors/different planes, points moving in different directions).
I am using Open Flash Charts v2. I have been trying to make Conditional line graph. But I couldn't find any straight forward way, example or any class for producing Conditional charts.
Example of Conditional Graph
So I thought to use some techniques to emulate conditional graph ,I made separate Line object for values above limit range and then this line is used to overlap the plotted line.
This techniques works some what ok ,but there are problems with it,
How to color or place the conditional colored line exactly above the limit.
Remove tooltip and dot from limit line.
Tooltip of conditional line(red) and plotted line(green) are both shown ,I only need tooltip of green line.
Conditional Line Graph Problem illustrated
Source Code: // C#
var chart = new OpenFlashChart.OpenFlashChart();
var data1 = new List<double?> { 1, 3, 4, 5, 2, 1, 6, 7 };//>4=
var overlap = new List<double?> { null, null, 4, 5, null, null, null, null };
var overlap2 = new List<double?> { null, null, null, null, null, null, 6, 7 };
var limitData = new List<double?> { 4, 4, 4, 4, 4, 4, 4, 4 };
var line1 = new Line();
line1.Values = data1;
//line1.HaloSize = 0;
line1.Width = 2;
line1.DotSize = 5;
line1.DotStyleType.Tip = "#x_label#<br>#val#";
line1.Colour = "#37c855";
line1.Tooltip = "#val#";
var overLine = new Line();
overLine.Values = overlap;
//overLine.HaloSize = 0;
overLine.Width = 2;
overLine.DotSize = 5;
overLine.DotStyleType.Tip = "#x_label#<br>#val#";
overLine.Colour = "#d81417";
overLine.Tooltip = "#val#";
var overLine2 = new Line();
overLine2.Values = overlap2;
//overLine2.HaloSize = 0;
overLine2.Width = 2;
overLine2.DotSize = 5;
//overLine2.DotStyleType.Tip = "#x_label#<br>#val#";
//overLine2.DotStyleType.Type = DotType.DOT;
overLine2.Colour = "#d81417";
overLine2.Tooltip = "#val#";
var limit = new Line();
limit.Values = limitData;
limit.Width = 2;
limit.Colour = "#ff0000";
limit.HaloSize = -1;
limit.DotSize = -1;
// limit.DotStyleType.Tip = "";
limit.DotStyleType.Type = null;
//limit.Tooltip = "";
chart.AddElement(line1);
chart.AddElement(overLine);
chart.AddElement(overLine2);
chart.AddElement(limit);
chart.Y_Legend = new Legend("Experiment");
chart.Title = new Title("Conditional Line Graph");
chart.Y_Axis.SetRange(0, 10);
chart.X_Axis.Labels.Color = "#e43456";
chart.X_Axis.Steps = 4;
chart.Tooltip = new ToolTip("#val#");
chart.Tooltip.Shadow = true;
chart.Tooltip.Colour = "#e43456";
chart.Tooltip.MouseStyle = ToolTipStyle.CLOSEST;
Response.Clear();
Response.CacheControl = "no-cache";
Response.Write(chart.ToPrettyString());
Response.End();
Note:
I have already downloaded the OFC (Open Flash Charts) source ,If I modify the OFC Line.as source than how would I be able to generate json for the changed graph ? ,b/c I'm currently using .Net library for the json generation for OFC charts,please do let me know this also.
Update:
I have modified the source code on the advice of David Mears I'm using FlashDevelop for ActionScript.
P.S: I'm open for ideas if another library can do this job.
If you don't mind a little rebuilding, you can get the source of OFC here and modify the Line.solid_line() method in open-flash-chart/charts/Line.as to do this fairly easily.
In order to set the extra chart details through JSON using the .NET library, you'll also have to modify OpenFlashChart/LineBase.cs to add alternative colour and boundary properties. I'm not hugely familiar with .NET, but based on the existing properties you might add something like this:
private double boundary;
private string altcolour;
[JsonProperty("boundary")]
public virtual double Boundary
{
set { this.boundary = value; }
get { return this.boundary; }
}
[JsonProperty("alt-colour")]
public virtual string AltColour
{
set { this.altcolour = value; }
get { return this.altcolour; }
}
Then I believe the following should work in Line.as:
public function solid_line(): void {
var first:Boolean = true;
var i:Number;
var tmp:Sprite;
var x:Number;
var y:Number;
var last_e:Element;
var ratio:Number;
for ( i=0; i < this.numChildren; i++ ) {
// Step through every child object.
tmp = this.getChildAt(i) as Sprite;
// Only include data Elements, ignoring extra children such as line masks.
if( tmp is Element )
{
var e:Element = tmp as Element;
if( first )
{
if (this.props.get('alt-colour') != Number.NEGATIVE_INFINITY) {
if (e._y >= this.props.get_colour('boundary'))
{
// Line starts below boundary, set alt line colour.
this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('alt-colour') );
}
else
{
// Line starts above boundary, set normal line colour.
this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('colour') );
}
}
// Move to the first point.
this.graphics.moveTo(e.x, e.y);
x = e.x;
y = e.y;
first = false;
}
else
{
if (this.props.get('alt-colour') != Number.NEGATIVE_INFINITY) {
if (last_e._y < this.props.get_colour('boundary') && e._y >= this.props.get_colour('boundary'))
{
// Line passes below boundary. Draw first section and switch to alt colour.
ratio = (this.props.get_colour('boundary') - last_e._y) / (e._y - last_e._y);
this.graphics.lineTo(last_e.x + (e.x - last_e.x) * ratio, last_e.y + (e.y - last_e.y) * ratio);
this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('alt-colour') );
}
else if (last_e._y >= this.props.get_colour('boundary') && e._y < this.props.get_colour('boundary'))
{
// Line passes above boundary. Draw first section and switch to normal colour.
ratio = (this.props.get_colour('boundary') - last_e._y) / (e._y - last_e._y);
this.graphics.lineTo(last_e.x + (e.x - last_e.x) * ratio, last_e.y + (e.y - last_e.y) * ratio);
this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('colour') );
}
}
// Draw a line to the next point.
this.graphics.lineTo(e.x, e.y);
}
last_e = e;
}
}
if ( this.props.get('loop') ) {
// close the line loop (radar charts)
this.graphics.lineTo(x, y);
}
}
With the new open-flash-chart.swf, you should be able to just set your new properties on line1:
line1.Boundary = 4;
line1.AltColour = "#d81417";