September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @return {boolean} true if (lng, lat) is in bounds
|
||||
*/
|
||||
function contains(bounds, lat, lng) {
|
||||
//https://rosettacode.org/wiki/Ray-casting_algorithm
|
||||
var count = 0;
|
||||
for (var b = 0; b < bounds.length; b++) {
|
||||
var vertex1 = bounds[b];
|
||||
var vertex2 = bounds[(b + 1) % bounds.length];
|
||||
if (west(vertex1, vertex2, lng, lat))
|
||||
++count;
|
||||
}
|
||||
return count % 2;
|
||||
|
||||
/**
|
||||
* @return {boolean} true if (x,y) is west of the line segment connecting A and B
|
||||
*/
|
||||
function west(A, B, x, y) {
|
||||
if (A.y <= B.y) {
|
||||
if (y <= A.y || y > B.y ||
|
||||
x >= A.x && x >= B.x) {
|
||||
return false;
|
||||
} else if (x < A.x && x < B.x) {
|
||||
return true;
|
||||
} else {
|
||||
return (y - A.y) / (x - A.x) > (B.y - A.y) / (B.x - A.x);
|
||||
}
|
||||
} else {
|
||||
return west(B, A, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var square = {name: 'square', bounds: [{x: 0, y: 0}, {x: 20, y: 0}, {x: 20, y: 20}, {x: 0, y: 20}]};
|
||||
var squareHole = {
|
||||
name: 'squareHole',
|
||||
bounds: [{x: 0, y: 0}, {x: 20, y: 0}, {x: 20, y: 20}, {x: 0, y: 20}, {x: 5, y: 5}, {x: 15, y: 5}, {x: 15, y: 15}, {x: 5, y: 15}]
|
||||
};
|
||||
var strange = {
|
||||
name: 'strange',
|
||||
bounds: [{x: 0, y: 0}, {x: 5, y: 5}, {x: 0, y: 20}, {x: 5, y: 15}, {x: 15, y: 15}, {x: 20, y: 20}, {x: 20, y: 0}]
|
||||
};
|
||||
var hexagon = {
|
||||
name: 'hexagon',
|
||||
bounds: [{x: 6, y: 0}, {x: 14, y: 0}, {x: 20, y: 10}, {x: 14, y: 20}, {x: 6, y: 20}, {x: 0, y: 10}]
|
||||
};
|
||||
|
||||
var shapes = [square, squareHole, strange, hexagon];
|
||||
var testPoints = [{lng: 10, lat: 10}, {lng: 10, lat: 16}, {lng: -20, lat: 10},
|
||||
{lng: 0, lat: 10}, {lng: 20, lat: 10}, {lng: 16, lat: 10}, {lng: 20, lat: 20}];
|
||||
|
||||
for (var s = 0; s < shapes.length; s++) {
|
||||
var shape = shapes[s];
|
||||
for (var tp = 0; tp < testPoints.length; tp++) {
|
||||
var testPoint = testPoints[tp];
|
||||
console.log(JSON.stringify(testPoint) + '\tin ' + shape.name + '\t' + contains(shape.bounds, testPoint.lat, testPoint.lng));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package ray_casting
|
||||
|
||||
import java.lang.Double.*
|
||||
import java.lang.Math.*
|
||||
import java.lang.Double.MAX_VALUE
|
||||
import java.lang.Double.MIN_VALUE
|
||||
import java.lang.Math.abs
|
||||
|
||||
data class Point(val x: Double, val y: Double)
|
||||
|
||||
|
|
@ -9,8 +8,8 @@ data class Edge(val s: Point, val e: Point) {
|
|||
operator fun invoke(p: Point) : Boolean = when {
|
||||
s.y > e.y -> Edge(e, s).invoke(p)
|
||||
p.y == s.y || p.y == e.y -> invoke(Point(p.x, p.y + epsilon))
|
||||
p.y > e.y || p.y < s.y || p.x > max(s.x, e.x) -> false
|
||||
p.x < min(s.x, e.x) -> true
|
||||
p.y > e.y || p.y < s.y || p.x > Math.max(s.x, e.x) -> false
|
||||
p.x < Math.min(s.x, e.x) -> true
|
||||
else -> {
|
||||
val blue = if (abs(s.x - p.x) > MIN_VALUE) (p.y - s.y) / (p.x - s.x) else MAX_VALUE
|
||||
val red = if (abs(s.x - e.x) > MIN_VALUE) (e.y - s.y) / (e.x - s.x) else MAX_VALUE
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
package ray_casting
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val figures = arrayOf(Figure("Square", arrayOf(Edge(Point(0.0, 0.0), Point(10.0, 0.0)), Edge(Point(10.0, 0.0), Point(10.0, 10.0)),
|
||||
Edge(Point(10.0, 10.0), Point(0.0, 10.0)),Edge(Point(0.0, 10.0), Point(0.0, 0.0)))),
|
||||
|
|
|
|||
|
|
@ -1,75 +0,0 @@
|
|||
#lang racket
|
||||
|
||||
(module pip racket
|
||||
(require racket/contract)
|
||||
|
||||
(provide point)
|
||||
(provide seg)
|
||||
(provide (contract-out [point-in-polygon? (->
|
||||
point?
|
||||
list?
|
||||
boolean?)]))
|
||||
|
||||
(struct point (x y) #:transparent)
|
||||
(struct seg (Ax Ay Bx By))
|
||||
(define ε 0.000001)
|
||||
(define (neq? x y) (not (eq? x y)))
|
||||
|
||||
(define (ray-cross-seg? r s)
|
||||
(let* ([Ax (seg-Ax s)] [Ay (seg-Ay s)]
|
||||
[Bx (seg-Bx s)] [By (seg-By s)]
|
||||
[Px (point-x r)] [Pyo (point-y r)]
|
||||
[Py (+ Pyo (if (or (eq? Pyo Ay)
|
||||
(eq? Pyo By))
|
||||
ε 0))])
|
||||
|
||||
(cond [(or (< Py Ay) (> Py By)) #f]
|
||||
[(> Px (max Ax Bx)) #f]
|
||||
[(< Px (min Ax Bx)) #t]
|
||||
[else
|
||||
(let ([red (if (neq? Ax Px)
|
||||
(/ (- By Ay) (- Bx Ax))
|
||||
+inf.0)]
|
||||
[blue (if (neq? Ax Px)
|
||||
(/ (- Py Ax) (- Px Ax))
|
||||
+inf.0)])
|
||||
(if (>= blue red) #t #f))])))
|
||||
|
||||
(define (point-in-polygon? point polygon)
|
||||
(odd?
|
||||
(for/fold ([c 0]) ([seg polygon])
|
||||
(+ c (if (ray-cross-seg? point seg) 1 0))))))
|
||||
|
||||
(require 'pip)
|
||||
|
||||
(define test-point-list
|
||||
(list
|
||||
(point 5.0 5.0)
|
||||
(point 5.0 8.0)
|
||||
(point -10.0 5.0)
|
||||
(point 0.0 5.0)
|
||||
(point 10.0 5.0)
|
||||
(point 8.0 5.0)
|
||||
(point 10.0 10.0)))
|
||||
|
||||
(define square
|
||||
(list (seg 0.0 0.0 10.0 0.0)
|
||||
(seg 10.0 0.0 10.0 10.0)
|
||||
(seg 10.0 10.0 0.0 10.0)
|
||||
(seg 0.0 0.0 0.0 10.0)))
|
||||
|
||||
(define exagon
|
||||
(list (seg 3.0 0.0 7.0 0.0)
|
||||
(seg 7.0 0.0 10.0 5.0)
|
||||
(seg 10.0 5.0 7.0 10.0)
|
||||
(seg 7.0 10.0 3.0 10.0)
|
||||
(seg 0.0 5.0 3.0 10.0)
|
||||
(seg 3.0 0.0 0.0 5.0)))
|
||||
|
||||
(define (test-figure fig name)
|
||||
(printf "\ntesting ~a: \n" name)
|
||||
(for ([p test-point-list])
|
||||
(printf "testing ~v: ~a\n" p (point-in-polygon? p fig))))
|
||||
|
||||
(test-figure square "square")
|
||||
(test-figure exagon "exagon")
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
testing square:
|
||||
testing (point 5.0 5.0): #t
|
||||
testing (point 5.0 8.0): #t
|
||||
testing (point -10.0 5.0): #f
|
||||
testing (point 0.0 5.0): #f
|
||||
testing (point 10.0 5.0): #t
|
||||
testing (point 8.0 5.0): #t
|
||||
testing (point 10.0 10.0): #f
|
||||
|
||||
testing exagon:
|
||||
testing (point 5.0 5.0): #t
|
||||
testing (point 5.0 8.0): #t
|
||||
testing (point -10.0 5.0): #f
|
||||
testing (point 0.0 5.0): #f
|
||||
testing (point 10.0 5.0): #t
|
||||
testing (point 8.0 5.0): #t
|
||||
testing (point 10.0 10.0): #f
|
||||
119
Task/Ray-casting-algorithm/Rust/ray-casting-algorithm.rust
Normal file
119
Task/Ray-casting-algorithm/Rust/ray-casting-algorithm.rust
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
use std::f64;
|
||||
use std::clone::Clone;
|
||||
|
||||
const _EPS: f64 = 0.00001;
|
||||
const _MIN: f64 = f64::MIN_POSITIVE;
|
||||
const _MAX: f64 = f64::MAX;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Point {
|
||||
x: f64,
|
||||
y: f64
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Edge {
|
||||
pt1: Point,
|
||||
pt2: Point
|
||||
}
|
||||
|
||||
impl Edge {
|
||||
fn new(pt1: (f64, f64), pt2: (f64, f64)) -> Edge {
|
||||
Edge { pt1: Point {x: pt1.0, y: pt1.1}, pt2: Point {x: pt2.0, y: pt2.1} }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Polygon{
|
||||
edges: Vec<Edge> // Polygon has to be created with counter-clockwise coordinates
|
||||
}
|
||||
|
||||
fn pt_in_polygon(pt: &Point, poly: &Polygon) -> bool {
|
||||
poly.edges.iter()
|
||||
.map(|edge| ray_intersect_seg(pt, edge))
|
||||
.fold(0u8, |sum, val| sum + (val as u8)) % 2 == 1
|
||||
}
|
||||
|
||||
fn ray_intersect_seg(p: &Point, edge: &Edge) -> bool {
|
||||
let mut pt = p.clone();
|
||||
let (mut a, mut b): (&Point, &Point) = (&edge.pt1, &edge.pt2);
|
||||
if a.y > b.y {
|
||||
let t = a; a = b; b = t;
|
||||
}
|
||||
if pt.y == a.y || pt.y == b.y {
|
||||
pt = Point {x: pt.x, y: pt.y + _EPS};
|
||||
}
|
||||
if (pt.y > b.y || pt.y < a.y) || pt.x > a.x.max(b.x) {
|
||||
return false;
|
||||
}
|
||||
if pt.x < a.x.min(b.x) {
|
||||
return true;
|
||||
} else {
|
||||
let m_red = if (a.x - b.x).abs() > _MIN { (b.y - a.y) / (b.x - a.x) } else { _MAX };
|
||||
let m_blue = if (a.x - pt.x).abs() > _MIN { (pt.y - a.y) / (pt.x - a.x) } else { _MAX };
|
||||
return m_blue >= m_red;
|
||||
}
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let p = |x,y| Point {x: x, y: y};
|
||||
let testpoints = vec![p(5.0, 5.0), p(5.0, 8.0), p(-10.0, 5.0), p(0.0, 5.0), p(10.0, 5.0), p(8.0, 5.0), p(10.0, 10.0)];
|
||||
let poly_square = Polygon {
|
||||
edges: vec![
|
||||
Edge::new((0.0, 0.0), (10.0, 0.0)),
|
||||
Edge::new((10.0, 0.0), (10.0, 10.0)),
|
||||
Edge::new((10.0, 10.0), (0.0, 10.0)),
|
||||
Edge::new((0.0, 10.0), (0.0, 0.0))
|
||||
]
|
||||
};
|
||||
let poly_square_hole = Polygon {
|
||||
edges: vec![
|
||||
Edge::new((0.0, 0.0), (10.0, 0.0)),
|
||||
Edge::new((10.0, 0.0), (10.0, 10.0)),
|
||||
Edge::new((10.0, 10.0), (0.0, 10.0)),
|
||||
Edge::new((0.0, 10.0), (0.0, 0.0)),
|
||||
Edge::new((2.5, 2.5), (7.5, 2.5)),
|
||||
Edge::new((7.5, 2.5), (7.5, 7.5)),
|
||||
Edge::new((7.5, 7.5), (2.5, 7.5)),
|
||||
Edge::new((2.5, 7.5), (2.5, 2.5))
|
||||
]
|
||||
};
|
||||
let poly_strange = Polygon {
|
||||
edges: vec![
|
||||
Edge::new((0.0, 0.0), (2.5, 2.5)),
|
||||
Edge::new((2.5, 2.5), (0.0, 10.0)),
|
||||
Edge::new((0.0, 10.0), (2.5, 7.5)),
|
||||
Edge::new((2.5, 7.5), (7.5, 7.5)),
|
||||
Edge::new((7.5, 7.5), (10.0, 10.0)),
|
||||
Edge::new((10.0, 10.0), (10.0, 0.0)),
|
||||
Edge::new((10.0, 0.0), (2.5, 2.5))
|
||||
]
|
||||
};
|
||||
let poly_hexagon = Polygon {
|
||||
edges: vec![
|
||||
Edge::new((3.0, 0.0), (7.0, 0.0)),
|
||||
Edge::new((7.0, 0.0), (10.0, 5.0)),
|
||||
Edge::new((10.0, 5.0), (7.0, 10.0)),
|
||||
Edge::new((7.0, 10.0), (3.0, 10.0)),
|
||||
Edge::new((3.0, 10.0), (0.0, 5.0)),
|
||||
Edge::new((0.0, 5.0), (3.0, 0.0))
|
||||
]
|
||||
};
|
||||
print!("\nSquare :");
|
||||
for pt in testpoints.iter() {
|
||||
print!(" {:?}", pt_in_polygon(pt, &poly_square));
|
||||
}
|
||||
print!("\nSquare with hole:");
|
||||
for pt in testpoints.iter() {
|
||||
print!(" {:?}", pt_in_polygon(pt, &poly_square_hole));
|
||||
}
|
||||
print!("\nStrange polygon :");
|
||||
for pt in testpoints.iter() {
|
||||
print!(" {:?}", pt_in_polygon(pt, &poly_strange));
|
||||
}
|
||||
print!("\nHexagon :");
|
||||
for pt in testpoints.iter() {
|
||||
print!(" {:?}", pt_in_polygon(pt, &poly_hexagon));
|
||||
}
|
||||
print!("\n");
|
||||
}
|
||||
17
Task/Ray-casting-algorithm/Zkl/ray-casting-algorithm-1.zkl
Normal file
17
Task/Ray-casting-algorithm/Zkl/ray-casting-algorithm-1.zkl
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const E = 0.0001;
|
||||
|
||||
fcn rayHitsSeg([(Px,Py)],[(Ax,Ay)],[(Bx,By)]){ // --> Bool
|
||||
if(Py==Ay or Py==By) Py+=E;
|
||||
if(Py<Ay or Py>By or Px>Ax.max(Bx)) False
|
||||
else if(Px<Ax.min(Bx)) True
|
||||
else try{ ( (Py - Ay)/(Px - Ax) )>=( (By - Ay)/(Bx - Ax) ) } //blue>=red
|
||||
catch(MathError){ Px==Ax } // divide by zero == ∞, only blue?
|
||||
}
|
||||
|
||||
fcn pointInPoly(point, polygon){ // --> Bool, polygon is ( (a,b),(c,d).. )
|
||||
polygon.filter('wrap([(ab,cd)]){ a,b:=ab; c,d:=cd;
|
||||
if(b<=d) rayHitsSeg(point,ab,cd); // left point has smallest y coordinate
|
||||
else rayHitsSeg(point,cd,ab);
|
||||
})
|
||||
.len().isOdd; // True if crossed an odd number of borders ie inside polygon
|
||||
}
|
||||
50
Task/Ray-casting-algorithm/Zkl/ray-casting-algorithm-2.zkl
Normal file
50
Task/Ray-casting-algorithm/Zkl/ray-casting-algorithm-2.zkl
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
polys:=T( //(name,( ((a,b),(c,d)),((a,b),(c,d))... ), ... )==(nm,(ln,ln..) ..)
|
||||
T("squared",
|
||||
T(T(T( 0.0, 0.0), T(10.0, 0.0)),
|
||||
T(T(10.0, 0.0), T(10.0, 10.0)),
|
||||
T(T(10.0, 10.0), T( 0.0, 10.0)),
|
||||
T(T( 0.0, 10.0), T( 0.0, 0.0)))),
|
||||
T("squaredhole",
|
||||
T(T(T( 0.0, 0.0), T(10.0, 0.0)),
|
||||
T(T(10.0, 0.0), T(10.0, 10.0)),
|
||||
T(T(10.0, 10.0), T( 0.0, 10.0)),
|
||||
T(T( 0.0, 10.0), T( 0.0, 0.0)),
|
||||
T(T( 2.5, 2.5), T( 7.5, 2.5)),
|
||||
T(T( 7.5, 2.5), T( 7.5, 7.5)),
|
||||
T(T( 7.5, 7.5), T( 2.5, 7.5)),
|
||||
T(T( 2.5, 7.5), T( 2.5, 2.5)))),
|
||||
T("strange",
|
||||
T(T(T( 0.0, 0.0), T( 2.5, 2.5)),
|
||||
T(T( 2.5, 2.5), T( 0.0, 10.0)),
|
||||
T(T( 0.0, 10.0), T( 2.5, 7.5)),
|
||||
T(T( 2.5, 7.5), T( 7.5, 7.5)),
|
||||
T(T( 7.5, 7.5), T(10.0, 10.0)),
|
||||
T(T(10.0, 10.0), T(10.0, 0.0)),
|
||||
T(T(10.0, 0.0), T( 2.5, 2.5)),
|
||||
T(T( 2.5, 2.5), T( 0.0, 0.0)))), # conjecturally close polygon
|
||||
T("exagon",
|
||||
T(T(T( 3.0, 0.0), T( 7.0, 0.0)),
|
||||
T(T( 7.0, 0.0), T(10.0, 5.0)),
|
||||
T(T(10.0, 5.0), T( 7.0, 10.0)),
|
||||
T(T( 7.0, 10.0), T( 3.0, 10.0)),
|
||||
T(T( 3.0, 10.0), T( 0.0, 5.0)),
|
||||
T(T( 0.0, 5.0), T( 3.0, 0.0)))),
|
||||
);
|
||||
|
||||
testPoints:=T(
|
||||
T( 5.0, 5.0),
|
||||
T( 5.0, 8.0),
|
||||
T(-10.0, 5.0),
|
||||
T( 0.0, 5.0),
|
||||
T( 10.0, 5.0),
|
||||
T( 8.0, 5.0),
|
||||
T( 10.0, 10.0)
|
||||
);
|
||||
|
||||
foreach name,polywanna in (polys){
|
||||
name.println();
|
||||
foreach testPoint in (testPoints){
|
||||
println("\t(%6.1f,%6.1f)\t".fmt(testPoint.xplode()),
|
||||
pointInPoly(testPoint,polywanna) and "IN" or "OUT");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue