Compute distance in Cartesian Coordinate System in Mathematica
Asked Answered
H

2

5

Analyzing Eye-movements on a screen, I set my origin to the bottom left corner of it (Hard to modify at that point).

Trying to compute distance between some points and the center of the screen I use the simple formula displayed below. Problem is that using this in conditional statement, it gets ugly.

Sqrt[
(
(fixationX - centerX)^2 + (fixationY - centerY)^2
)
]

Is there a way to customize Norm to compute distance between points and not between a point and the origin ?

Or in my case, set the origin to be at the "center" of the current coordinate system ?

Hippolytus answered 12/6, 2011 at 14:10 Comment(0)
P
4

A slight variation of Simon's method is to use a default value in the function, rather than a global variable ($Center).

Suppose your default origin is (5, 5), then:

myNorm[pos:{_, _}, center_:{5, 5}] := EuclideanDistance[pos, center]

Notice the use of _:{5, 5} to define the default value.

Now you can do:

myNorm[{5, 7}]

(* Out[]= 2 *)

Or temporarily use a different the center with:

myNorm[{5, 7}, {8, 8}]

(* Out[]= Sqrt[10] *)

For this simple function, you could use EuclideanDistance in the second case instead, but I hope you can see the utility of this method were the definition of myNorm more complex.

The downside to this method is that you cannot easily change the default center.


Another variation that does allow one to easily change the default center, but is more verbose, is to use Options:

Options[myNorm2] = {Center -> {5, 5}};

myNorm2[pos : {_, _}, OptionsPattern[]] := 
 EuclideanDistance[pos, OptionValue[Center]]

Syntax is:

myNorm2[{5, 7}]

myNorm2[{5, 7}, Center -> {8, 8}]
   2
   Sqrt[10]

Changing the default center:

SetOptions[myNorm2, Center -> {8, 8}];

myNorm2[{5, 7}]
   Sqrt[10]
Phantasmagoria answered 12/6, 2011 at 22:20 Comment(4)
@Hippolytus you're welcome. Please see my updated answer for another method.Phantasmagoria
I've made exactly the same mistake you had with Default in your first version. I was so far along in the project before I noticed that I just put a comment about it at the top which said "if you change $xyz, you need to redefine the following..."!Legal
@Legal if it got both of us, I am going to post a question about this. The fact that DefaultValues[f] changes without effect is confusing.Phantasmagoria
Yeah, it might be a "bug". You can see why a f[a_:$d] := ... definition would not care about changing $d. But just looking at the downvalues of Default[g]=$d ; g[a_.] := ... shows no reason why changing either of Default[g] or $d has no effect.Legal
L
4

Can you just use EuclideanDistance

In[1]:= EuclideanDistance[{x,y}, {cx,cy}]
Out[1]= Sqrt[Abs[-cx +x ]^2 + Abs[-cy + y]^2]

Or define a $Center and a new CNorm, e.g.

$Center = {cx, cy};
CNorm[pos:{x_, y_}] := EuclideanDistance[pos, $Center]
Legal answered 12/6, 2011 at 14:21 Comment(4)
Thank You, I posted this before I saw your e-mail,I might wait to implement now that my function works !Hippolytus
@500, getting email support from Simon too, eh? I wish I had the kind of support your getting when I was learning Mathematica. :-)Phantasmagoria
@Mr Wizard, Seriously, it is amazing, this generosity and expertise fueled me with motivation ! I will send you my notebook soon with the hope you`ll like it !Hippolytus
@Hippolytus Thanks, I am sure I will. If you saw my answer below already, notice that I just changed it. I make a mistake, as I have not used Default in a while. I am (re)learning too.Phantasmagoria
P
4

A slight variation of Simon's method is to use a default value in the function, rather than a global variable ($Center).

Suppose your default origin is (5, 5), then:

myNorm[pos:{_, _}, center_:{5, 5}] := EuclideanDistance[pos, center]

Notice the use of _:{5, 5} to define the default value.

Now you can do:

myNorm[{5, 7}]

(* Out[]= 2 *)

Or temporarily use a different the center with:

myNorm[{5, 7}, {8, 8}]

(* Out[]= Sqrt[10] *)

For this simple function, you could use EuclideanDistance in the second case instead, but I hope you can see the utility of this method were the definition of myNorm more complex.

The downside to this method is that you cannot easily change the default center.


Another variation that does allow one to easily change the default center, but is more verbose, is to use Options:

Options[myNorm2] = {Center -> {5, 5}};

myNorm2[pos : {_, _}, OptionsPattern[]] := 
 EuclideanDistance[pos, OptionValue[Center]]

Syntax is:

myNorm2[{5, 7}]

myNorm2[{5, 7}, Center -> {8, 8}]
   2
   Sqrt[10]

Changing the default center:

SetOptions[myNorm2, Center -> {8, 8}];

myNorm2[{5, 7}]
   Sqrt[10]
Phantasmagoria answered 12/6, 2011 at 22:20 Comment(4)
@Hippolytus you're welcome. Please see my updated answer for another method.Phantasmagoria
I've made exactly the same mistake you had with Default in your first version. I was so far along in the project before I noticed that I just put a comment about it at the top which said "if you change $xyz, you need to redefine the following..."!Legal
@Legal if it got both of us, I am going to post a question about this. The fact that DefaultValues[f] changes without effect is confusing.Phantasmagoria
Yeah, it might be a "bug". You can see why a f[a_:$d] := ... definition would not care about changing $d. But just looking at the downvalues of Default[g]=$d ; g[a_.] := ... shows no reason why changing either of Default[g] or $d has no effect.Legal

© 2022 - 2024 — McMap. All rights reserved.