I am trying to check if a point is in a cross shape. That looks like this
Not sure how to modify the pnpoly to suit this type of shape
bool PointInPolygon(vector<pair<int,int>> points,int x, int y) {
int i, j, nvert = points.size();
bool c = false;
for(i = 0, j = nvert- 1; i < nvert; j = i++) {
if( ( (points[i].second >= y) != (points[j].second >= y) ) &&
(x <= (points[j].first - points[i].first) * (y - points[i].second) / (points[j].second - points[i].second) + points[i].first)
)
c = !c;
}
Appreciate any help
While googling reveals, that the term "scanline" has gotten a new meaning recently, it used to be the name for an algorithm to detect intersections of lines and other geometric shapes.
The algorithms basic idea is to move a vertical "scan line" across the vertices from left to right and to record the vertical boundaries of the shape at that very x-coordinate (where the scanline is currently positioned).
Given you only have horizontal and vertical lines, the implementation of that idea can simply jump from x-coordinate of a vertex to the next, if the vertices are sorted in ascending order on the x-coordinate.
Since multiple points can share the same x-coordinate, all we need to note is, at that very x-coordinate, which are the highest and lowest y coordinates of those vertices, respectively.
Given that 32degree Celsius summertime heat, I was too lazy to create a C++ version of it. Instead, some quick hacking in Common Lisp. But it should be easy enough to read and translate. Instead of defining some kind of point structure, I simply took complex numbers, where your C++ program uses a std::pair<int,int>. realpart/imagpart obtain the real or imaginary part of a complex number, which, here is simply the x and y component of the vertex.
(defparameter *shape* '(#C(3 3) #C(3 6)
#C(5 6) #C(5 9)
#C(6 9) #C(6 6)
#C(6 3) #C(6 0)
#C(8 0) #C(8 3)
#C(11 3) #C(11 6)))
(defun point-in-shape-p (shape point)
(let ((x-sorted (sort
shape
#'(lambda (p1 p2)
(< (realpart p1)
(realpart p2))))))
(if (< (realpart point)
(realpart (first x-sorted)))
nil
(loop
with x-pivot = -1000000 ;; outside
with y-high = -1000000 ;; outside
with y-low = 100000 ;; outside
for v in x-sorted
when (> (realpart v) x-pivot)
do (progn
(setf x-pivot (realpart v))
(setf y-high -1000000)
(setf y-low 1000000))
when (> (imagpart v) y-high)
do (setf y-high (imagpart v))
when (< (imagpart v) y-low)
do (setf y-low (imagpart v))
when (and (<= (realpart point) x-pivot)
(<= (imagpart point) y-high)
(>= (imagpart point) y-low))
return t))))
Here a few test runs, I did for various points and the shape from your image:
CL-USER> (point-in-shape-p *shape* #C(7 8))
NIL
CL-USER> (point-in-shape-p *shape* #C(7 4))
T
CL-USER> (point-in-shape-p *shape* #C(9 2))
NIL
CL-USER> (point-in-shape-p *shape* #C(9 3))
T
No warranties, but I think it is looking good.
Related
I have lists similar to this :
'(
; element 1
(
((X hello))
)
; element 2
(
((X hello)(Y world))
((X hello) (Y earth))
((X hi) (Y planet))
)
; element 3
(
((Y world))
)
)
I'd like to make a loop or something that can give me an "intersection" of the elements in that list. For exemple for the list above the result should be something like that :
((X hello) (Y world))
Indeed this result is the only one that can satisfy the X and Y. I'm very new to clojure so if you also have advices for a better data structure, they're also welcome.
You need to re-think the problem a bit. Right now, an intersection would produce the null set.
In addition, you may wish to study the built-in functions like
https://clojuredocs.org/clojure.core/set
https://clojuredocs.org/clojure.set/intersection
The Clojure CheatSheet
I want to draw an sketch with eight pattern. Now I know how to draw circles in counterclockwise and clockwise directions. But I do not know how to combine them.
(defn draw-state [state]
(let [x (* 150 (quil.core/cos angle))
y (* 150 (quil.core/sin angle))]
(quil.core/ellipse x y 100 100)
(quil.core/ellipse y x 100 100)))
This function will draw two circles in opposite directions. But how to draw a sketch with 8 pattern?
A polar equation for an 8-type of curve =
r^2 = Cos[2t] (Sec[t])^4
where r = radius, t = angle
You could start with this.
I am using the following function to try to create a 64-bit hash of a string, but it is failing with an ArithmeticException even though I am using the "unchecked" version of the arithmetic operators.
user> (reduce (fn [h c]
(unchecked-add (unchecked-multiply h 31) (long c)))
1125899906842597
"hello")
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)
What am I doing wrong here?
have a hint here:
for whatever reason the first param in a function here is treated as integer. Adding type hint helps to solve this problem:
user> (reduce (fn [^long h c]
(unchecked-add (unchecked-multiply h 31) (long c)))
1125899906842597
"hello")
7096547112155234317
update:
moreover: it looks that it comes from the unchecked-multiply
user> (reduce (fn [h c]
(unchecked-add (unchecked-multiply ^long h 31) (long c)))
1125899906842597
"hello")
7096547112155234317
i will make some additional research, and update here, in case of any new information
update 2:
ok, that's what i've found out:
looking at the clojure's documentation at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java
we can see the following:
our case
static public Number unchecked_multiply(Object x, long y){return multiply(x,y);}
leads to:
static public Number multiply(Object x, long y){
return multiply(x,(Object)y);
}
then:
static public Number multiply(Object x, Object y){
return ops(x).combine(ops(y)).multiply((Number)x, (Number)y);
}
so at the end it calls multiply method from LongOps inner class.
final public Number multiply(Number x, Number y){
return num(Numbers.multiply(x.longValue(), y.longValue()));
}
so finally it leads us to a simple (checked?) multiply:
static public long multiply(long x, long y){
if (x == Long.MIN_VALUE && y < 0)
return throwIntOverflow();
long ret = x * y;
if (y != 0 && ret/y != x)
return throwIntOverflow();
return ret;
}
kaboom!
so i don't know whether it is a bug or the desired behavior, but it looks really weird to me.
so the only thing i could advice, is to always remember to typehint your values when using unchecked math in clojure.
You can get the behaviour you want by avoiding the function calls:
(loop [h 1125899906842597
cs "hello"]
(let [c (first cs)]
(if c
(recur (unchecked-add (unchecked-multiply h 31) (long c))
(rest cs))
h)))
;7096547112155234317
Why this is so, I don't know.
I'm trying to implement a simple logistic regression example in Clojure using the Incanter data analysis library. I've successfully coded the Sigmoid and Cost functions, but Incanter's BFGS minimization function seems to be causing me quite some trouble.
(ns ml-clj.logistic
(:require [incanter.core :refer :all]
[incanter.optimize :refer :all]))
(defn sigmoid
"compute the inverse logit function, large positive numbers should be
close to 1, large negative numbers near 0,
z can be a scalar, vector or matrix.
sanity check: (sigmoid 0) should always evaluate to 0.5"
[z]
(div 1 (plus 1 (exp (minus z)))))
(defn cost-func
"computes the cost function (J) that will be minimized
inputs:params theta X matrix and Y vector"
[X y]
(let
[m (nrow X)
init-vals (matrix (take (ncol X) (repeat 0)))
z (mmult X init-vals)
h (sigmoid z)
f-half (mult (matrix (map - y)) (log (sigmoid (mmult X init-vals))))
s-half (mult (minus 1 y) (log (minus 1 (sigmoid (mmult X init-vals)))))
sub-tmp (minus f-half s-half)
J (mmult (/ 1 m) (reduce + sub-tmp))]
J))
When I try (minimize (cost-func X y) (matrix [0 0])) giving minimize a function and starting params the REPL throws an error.
ArityException Wrong number of args (2) passed to: optimize$minimize clojure.lang.AFn.throwArity (AFn.java:437)
I'm very confused as to what exactly the minimize function is expecting.
For reference, I rewrote it all in python, and all of the code runs as expected, using the same minimization algorithm.
import numpy as np
import scipy as sp
data = np.loadtxt('testSet.txt', delimiter='\t')
X = data[:,0:2]
y = data[:, 2]
def sigmoid(X):
return 1.0 / (1.0 + np.e**(-1.0 * X))
def compute_cost(theta, X, y):
m = y.shape[0]
h = sigmoid(X.dot(theta.T))
J = y.T.dot(np.log(h)) + (1.0 - y.T).dot(np.log(1.0 - h))
cost = (-1.0 / m) * J.sum()
return cost
def fit_logistic(X,y):
initial_thetas = np.zeros((len(X[0]), 1))
myargs = (X, y)
theta = sp.optimize.fmin_bfgs(compute_cost, x0=initial_thetas,
args=myargs)
return theta
outputting
Current function value: 0.594902
Iterations: 6
Function evaluations: 36
Gradient evaluations: 9
array([ 0.08108673, -0.12334958])
I don't understand why the Python code can run successfully, but my Clojure implementation fails. Any suggestions?
Update
rereading the docstring for minimize i've been trying to calculate the derivative of cost-func which throws a new error.
(def grad (gradient cost-func (matrix [0 0])))
(minimize cost-func (matrix [0 0]) (grad (matrix [0 0]) X))
ExceptionInfo throw+: {:exception "Matrices of different sizes cannot be differenced.", :asize [2 1], :bsize [1 2]} clatrix.core/- (core.clj:950)
using trans to convert the 1xn col matrix to a nx1 row matrix just yields the same error with opposite errors.
:asize [1 2], :bsize [2 1]}
I'm pretty lost here.
I can't say anything about your implementation, but incanter.optimize/minimize expects (at least) three parameters and you're giving it only two:
Arguments:
f -- Objective function. Takes a collection of values and returns a scalar
of the value of the function.
start -- Collection of initial guesses for the minimum
f-prime -- partial derivative of the objective function. Takes
a collection of values and returns a collection of partial
derivatives with respect to each variable. If this is not
provided it will be estimated using gradient-fn.
Unfortunately, I'm not able to tell you directly what to supply (for f-prime?) here but maybe someone else is. Btw, I think the ArityException Wrong number of args (2) passed to [...] is actually quite helpful here.
Edit: Actually, I think the docstring above is not correct, since the source code does not use gradient-fn to estimate f-prime. Maybe, you can use incanter.optimize/gradient to generate your own?
First, Your cost function should have a parameter for theta like your python implementation however your implementation has fixed as initial-value.
Second, if your cost-func is correct, then you can call optimize like this
(optimize (fn [theta] (cost-func theta X y)) [0 0 0])
Hope this can help you.
I have been dealing many days with a problem without any success. In my programm I define a list, let's call it "L", by shifting a single geometrical object, a circle, many times. So L is composed by manu circles. The object circle is also a list which contains its properties: center (center . #V), (height . H), radius (radius . R), and so on. So, the property radius is a pair in the 3rd position of the list circle. If I do (object-property-value circle 'radius) = R. Now, what I want to do is to create a new list, L-disorder, composed by circles with the same positions of those of L but each with different (random) radius. Then, I try this:
(define L-disorder (map
(lambda(obj)
(set-cdr! (list-ref obj 3) (random:normal))
obj)
L))
My problem is that it changes the radius of all the circles the same way! And I want a different (random) value for all of them.
I would really thank any help or advise!!
If you want to create new list, you shouldn't use mutation functons (set-cdr!).
(map ) functions do all the magic for you: it iterates over source list, and creates new list.
(define L-disorder
(map (lambda (circle)
; here we creating new circle
(list (car circle) (cadr circle) (random:normal)))
L))