Map a Matrix to a Circular Frame Image - plot

I have a matrix and o want to map it to a circular frame. Each element in matrix should be mapped to a predefined position on the circular frame. What i am really do is dealing with the human brain signals recorded from different electrodes installed over the skull. This is the final plot i want to get:
http://www.ihr.mrc.ac.uk/img/research/2009/3/scan-banner.jpg
Any Sugestion?

Please, correct me if I'm wrong. I don't know what kind of data these electrodes are able to retrieve, but in any case, I think you can view them in two different natures: first, sampled data (a class that encapsulates all information gathered through one specific electrode) and second, a geographically mapping object, binding the data from each electrode to one specific location.
As for the first part, you can design whatever class you wish, according to your needs. This class may have but a single double value (like intensity or electric level, or whatever) or a complete set of variables or even other classes arranged in such a way that represent what you need.
As for the second part, as you want to map the data retrieved from each electrode into a pre-determined point in a circular area, I think a class having an horizontal and a vertical positioning value is good. This can be a java.awt.Point (which can map to the real X and Y position of the point you wish) or a custom class (non-related to any domain) with the two X and Y variables, that can translate to a real X and Y coordinate in the final image.
Something like that
public class Position {
private int x;
private int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
and
public class Sample {
private double electricalLevel;
private Position position;
public double getElectricalLevel() {
return electricalLevel;
}
public void setElectricalLevel(double electricalLevel) {
this.electricalLevel = electricalLevel;
}
public Position getPosition() {
return position;
}
public void setPosition(Position position) {
this.position = position;
}
}
Something like that.
Then you'll have to instantiate each Sample, map it to a Position instance and keep updating the values.
As for the mapping to the correct Position, you can have all the positions pre-calculated and entered as literals, or calculated from a positioning function. I think the pre-calculated positions are ok, as they are not prone to changing...
Then you'll have something like:
Sample s1 = new Sample();
s1.setPosition(new Position(100, 100));
Sample s2 = new Sample();
s2.setPosition(new Position(150, 80));
and so on, for each electrode.
As for the drawing itself, you'll have to dig into java imaging. This will not be so simple, because you're not really only plotting the points themselves. Actually, the colour of each point and its surrounding area will be a function of the sampled data, if I'm correct, as the colour seems to be reflecting the sampled data from that brain region.
To make things worse, the boundary areas between multiple points will influence each other, so that a colour gradient will be generated.
I suggest you first focus in the given scenario and that you ask about the painting and java imaging issue in other question.
Sorry, this is a really general answer, but it's as far as I can go with many assumptions and without knowing what exactly you're dealing with. I hope it helps, though.

Related

Given 3 or more numbers or vectors, how do I interpolate between them based on a percentage?

I want to know the most basic math principles I need to interpolate a value between 3 or more other values, based on a linear percentage; as it would be applicable in programming.
For example, say I have "0", "100", "200", and I want the number that's at "50%". The math would then return something like "100" because 100 is at 50%.
Another example: I have 3 points somewhere in 3D space. If I do "75%" then the result would be a point that is exactly halfway between point 2 and 3, or if I do "25%" then it'll be half-way between 1 and 2.
Game engines like Unity use something like this for blending between multiple animations on a character, for another example.
What I've brainstormed so far is that I would somehow take the input value and find whatever the 2 neighboring "points" are closest to it (much harder in 3D or 2d space but manageable in 1d), then simply lerp between those two- but that requires me to figure out what percentage both of those points are at individually, and remap from "0 to 100%" to "A% to B%". I think it would work but It seems kind of complicated to me.
If possible, I'd like answers to include a C# example or language-agnostic psuitocode just so I can understand the math.
simple example for scalar float objects using piecewise linear interpolation:
int n=3; // number of your objects
float x[n]={ 0.5,2.0,10.0 }; // your objects
float get_object(float t) // linearly interpolate objects x[] based in parameter t = <0,1>, return value must be the same type as your objects
{
int ix;
float x0,x1; // the same type as your objects
// get segment ix and parameter t
t*=n; ix=floor(t); t-=ix;
// get closest known points x0,x1
x0=x[ix]; ix++;
if (ix<n) x1=x[ix]; else return x0;
// interpolate
return x0+(x1-x0)*t;
}
so if t=0 it returns first object in the x[] if it is t=1 is returns last and anything in between is linearly interpolated ... The idea is just to multiply our t by number of segments or point (depend on how you handle edge cases) which integer part of the result will give us index of closest 2 objects to our wanted one and then the fractional part of multiplied t will give us directly interpolation parameter in range <0,1> between the two closest points...
In case you objects are not with the same weight or are not uniformly sampled then you need to add interpolation with weights or use higher order polynomial (quadratic,cubic,...).
You can use this for "any" type T of objects you just have to implement operations T+T , T-T and T*float if they are not present.
If your gameObjects is at the same line try this code.
public Transform objStart;
public Transform objEnd;
public Transform square;
public float distance;
//percent .5 means 50%
[Range(0f,1f)]
public float percent;
public Vector3 distancePercentPosition;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//get distance between two object
distance = Vector3.Magnitude(objEnd.position - objStart.position);
//get position based on percent;
distancePercentPosition = (objEnd.position - objStart.position).normalized * percent * distance;
square.position = objStart.position + distancePercentPosition;
}
once you get the position between lines you can now map your gameobject in each position based on percent.

Moving along a path of straight line segments at constant speed

I have a list of vector points, which define a path of straight line segments to be followed by an object. Currently, I do linear interpolation to animate motion along the path like this:
public class Demo
{
public float speed = 1;
private List<Vector3> points;
private float t; // [0..1]
private Vector3 Evaluate(float t)
{
// Find out in between which points we currently are
int lastPointIndex = GetLast(t);
int nextPointIndex = GetNext(t);
// Obviously, I need to somehow transform parameter t
// to adjust for the individual length of each segment.
float segmentLength = GetLength(lastPointIndex, nextPointIndex);
// But how would I do this?
return Vector3.Lerp(points[lastPointIndex], points[nextPointIndex], t);
}
public void Update()
{
// Curve parameter t moves between 0 and 1 at constant speed.
t = Mathf.PingPong(Time.time * speed, 1);
// Then just get the evaluated position for the curve time, but
// this gives variant speed if points are not evenly spaced.
Vector3 position = Evaluate(t);
SetObjectPosition(position);
}
}
I realize, that to achieve constant speed, I need to rescale the parameter t to account for the length of each segment, but I seem to be unable to find out exactly how.
I also know, that I could approximate the path by moving towards the next point at my desired speed and only change direction, once I'm in close proximity or keep track of t as well and change direction once it moves over the next segment, but this seems hacky, when I actually know the exact length of each segment and should be able to interpolate this exactly.
That's actually quiet easy. First, define a speed you want for your object. For example, 6 units per second. That means if a line segment has a length of 6 units then your object will take 1 second to go from its start to its end point. This also means that if you have a line segment that is half that length (i.e. 3 units) it will take the object 0.5 second to cross it. So, what you have to do is calculate the length of all your line segments and divide that by the speed you want to go (3/6 = 0.5 = scaleFactor). Then instead of interpolating between 0 and 1, interpolate between 0 and 1*scaleFactor. Your code then becomes:
public class Demo
{
public float speed = 1;
private List<Vector3> points;
private float t; // [0..1]
private Vector3 Evaluate(float t)
{
// Find out in between which points we currently are
int lastPointIndex = GetLast(t);
int nextPointIndex = GetNext(t);
float segmentLength = GetLength(lastPointIndex, nextPointIndex);
float scaleFactor = segmentLength/speed;
// note that I divided t by scaleFactor instead of multiplication.
// That's because Lerp always takes an interval of [0..1]. So, we
// adjust the curve parameter instead.
return Vector3.Lerp(points[lastPointIndex], points[nextPointIndex], t/scaleFactor);
}
public void Update()
{
// Curve parameter t moves between 0 and 1 at constant speed.
t = Mathf.PingPong(Time.time * speed, 1);
// Then just get the evaluated position for the curve time, but
// this gives variant speed if points are not evenly spaced.
Vector3 position = Evaluate(t);
SetObjectPosition(position);
}
}

Add penalty to previous path on point graph to prevent u-turns? A* Pathfinding Project

I am using Aron Granberg's A* Pathfinding Project. So I have a point graph set up in this picture:
I have each car choosing a random node on the point graph and following a path to it.
Right now, the cars traveling on the road have a tendency to make u-turns to get to their next destination. For example, suppose the original path was from point A to point B. Once the car reaches point B, it then randomly chooses to travel to point C.
Is there any way where I can force it to always take the yellow path instead of the purple path to prevent u-turns? I was thinking something along the lines of setting penalties for the previous path, but the penalties would have to only apply to a single agent as I don't want the penalties to apply to the other cars on the road. Is there a feasible way to do this? I have included my pathfinding code below.
using UnityEngine;
using System.Collections;
using System.Linq;
//Note this line, if it is left out, the script won't know that the class 'Path' exists and it will throw compiler errors
//This line should always be present at the top of scripts which use %Pathfinding
using Pathfinding;
public class newPathfind : MonoBehaviour {
//The point to move to
private Vector3 targetPosition;
private bool pathComplete;
public bool ManualList = false;
//public int members = 0;
//private int x = 0;
public GameObject target1;
public GameObject target2;
public GameObject target3;
public GameObject target4;
public GameObject target5;
private GameObject[] Waypoints;
private GameObject[] oneway;
private GameObject[] twoway;
public static int randomPoint;
private Seeker seeker;
private CharacterController controller;
//The calculated path
public Path path;
//The AI's speed per second
public float speed = 500;
//The max distance from the AI to a waypoint for it to continue to the next waypoint
public float nextWaypointDistance = 3;
//The waypoint we are currently moving towards
private int currentWaypoint = 0;
public void Start () {
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
Vector3 randomLoc = Vector3.zero;
if (ManualList) {
Waypoints = new GameObject[5];
Waypoints[0] = target1;
Waypoints[1] = target2;
Waypoints[2] = target3;
Waypoints[3] = target4;
Waypoints[4] = target5;
} else {
//Waypoints = GameObject.FindGameObjectsWithTag("network");
twoway = GameObject.FindGameObjectsWithTag ("network");
oneway = GameObject.FindGameObjectsWithTag ("oneway");
Waypoints = oneway.Concat (twoway).ToArray ();
}
do {
randomPoint = Random.Range (0, Waypoints.Length-1);
randomLoc = Waypoints[randomPoint].transform.position;
targetPosition = new Vector3 (randomLoc.x, gameObject.transform.position.y, randomLoc.z);
} while ((Vector3.Distance(gameObject.transform.position, targetPosition) < 50f));
//Start a new path to the targetPosition, return the result to the OnPathComplete function
seeker.StartPath (transform.position,targetPosition, OnPathComplete);
}
public void OnPathComplete (Path p) {
Debug.Log ("Yey, we got a path back. Did it have an error? "+p.error);
if (!p.error) {
path = p;
//Reset the waypoint counter
currentWaypoint = 0;
pathComplete = true;
}
}
public void FixedUpdate () {
if (path == null) {
return;
}
if (currentWaypoint >= path.vectorPath.Count && pathComplete == true) {
Debug.Log ("End Of Path Reached");
Start();
pathComplete = false;
return;
}
//Direction to the next waypoint
Vector3 dir = Vector3.zero;
if (currentWaypoint >= 0 && currentWaypoint < path.vectorPath.Count) {
dir = (path.vectorPath [currentWaypoint] - transform.position).normalized;
}
if (dir != Vector3.zero) {
transform.rotation = Quaternion.LookRotation (dir);
}
dir *= speed * Time.fixedDeltaTime;
controller.SimpleMove (dir);
//Check if we are close enough to the next waypoint
//If we are, proceed to follow the next waypoint
if (Vector3.Distance (transform.position,path.vectorPath[currentWaypoint]) < nextWaypointDistance) {
currentWaypoint++;
return;
}
}
public void OnDisable () {
seeker.pathCallback -= OnPathComplete;
}
}
I couldn't find how to do this using Aron Granberg's A* Pathfinding Project, but essentially you'll need to change the cost of the last visited node to maybe about 3-5 times its normal cost (would probably need experimenting) before calling seeker.StartPath again.
I would assume that the pathfinder has some way of asking you what the cost for each node is. If the node is the same as the last node the unit visited, you would return a multiple of its actual cost. Of course, you will need to know for which unit it is pathing for.
Closest thing I could find (knowing nothing about the library) was GraphUpdates where you are able to apply penalties to various nodes:
GraphUpdateObject guo = new GraphUpdateObject(myBounds);
guo.addPenalty = 10000; //Here goes the penalty to apply, you need quite large values usually
AstarPath.active.UpdateGraphs (guo);
Not sure how you would tie this with a unit other than updating the graph before calling the seeker for a particular unit and making sure nobody else calls the seeker until that's done (very inefficient).
Difficult question... One thing you could do (for a car already traveling) is evaluate a straight line on the path of the car to the next intersection. That would be the next logical time that the driver would make a decision to recalculate their path. Doing it this way would tell the car to continue using the seeker until it found the starting node of the path (in this case it would drastically reduce your u-turn behavior) which happens to be at the next intersection making your hypothetical much less likely and closer mimick driving behavior.
Also on busy roads you may want to consider using the filter called alternative path... If you add this to your existing car prefab, you can create a penalty for too many other units taking the same path. If you set it to ...say 100, unless it was the only realistic path, after 10 cars took the same path likely you would have cars taking alternate routes
Just my two cents
My edited two cents, adding weights to roads, unless it is the entirety of the road (ie dirt vs. pavement) isnt going to be too feasible. Unless I have missed something in the docs (let me know if I did because I want to use it) you are unable to get the weight for a given node/waypoint.You can however choose between different paths with different penalties. (IE you cant do path.vectorPath[currentWaypoint].weight, but you can do path.GetTagPenalty and choose an alternate path)
Angle Penalty in the "Advanced" section may help here.

Usage of Map and Translate Functions in Processing

New to Processing working on understanding this code:
import com.onformative.leap.LeapMotionP5;
import java.util.*;
LeapMotionP5 leap;
LinkedList<Integer> values;
public void setup() {
size(800, 300);
frameRate(120); //Specifies the number of frames to be displayed every second
leap = new LeapMotionP5(this);
values = new LinkedList<Integer>();
stroke(255);
}
int lastY = 0;
public void draw() {
**translate(0, 180)**; //(x, y, z)
background(0);
if (values.size() >= width) {
values.removeFirst();
}
values.add((int) leap.getVelocity(leap.getHand(0)).y);
System.out.println((int) leap.getVelocity(leap.getHand(0)).y);
int counter = 0;
** for (Integer val : values)** {
**val = (int) map(val, 0, 1500, 0, height);**
line(counter, val, counter - 1, lastY);
point(counter, val);
lastY = val;
counter++;
}
** line(0, map(1300, 0, 1500, 0, height), width, map(1300, 0, 1500, 0, height)); //(x1, y1, x2, y2)**
}
It basically draw of graph of movement detected on the y axis using the Leap Motion sensor. Output looks like this:
I eventually need to do something similar to this that would detect amplitude instead of velocity simultaneously on all 3 axis instead of just the y.
The use of Map and Translate are whats really confusing me. I've read the definitions of these functions on the Processing website so I know what they are and the syntax, but what I dont understand is the why?! (which is arguably the most important part.
I am asking if someone can provide simple examples that explain the WHY behind using these 2 functions. For instance, given a program that needs to do A, B, and C, with data foo, y, and x, you would use Map or Translate because A, B, and C.
I think programming guides often overlook this important fact but to me it is very important to truly understanding a function.
Bonus points for explaining:
for (Integer val : values) and LinkedList<Integer> values; (cant find any documentation on the processing website for these)
Thanks!
First, we'll do the easiest one. LinkedList is a data structure similar to ArrayList, which you may be more familiar with. If not, then it's just a list of values (of the type between the angle braces, in this case integer) that you can insert and remove from. It's a bit complicated on the inside, but if it doesn't appear in the Processing documentation, it's a safe bet that it's built into Java itself (java documentation).
This line:
for (Integer val : values)
is called a "for-each" or "foreach" loop, which has plenty of very good explanation on the internet, but I'll give a brief explanation here. If you have some list (perhaps a LinkedList, perhaps an ArrayList, whatever) and want to do something with all the elements, you might do something like this:
for(int i = 0; i < values.size(); i++){
println(values.get(i)); //or whatever
println(values.get(i) * 2);
println(pow(values.get(i),3) - 2*pow(values.get(i),2) + values.get(i));
}
If you're doing a lot of manipulation with each element, it quickly gets tedious to write out values.get(i) each time. The solution would be to capture values.get(i) into some variable at the start of the loop and use that everywhere instead. However, this is not 100% elegant, so java has a built-in way to do this, which is the for-each loop. The code
for (Integer val : values){
//use val
}
is equivalent to
for(int i = 0; i < values.size(); i++){
int val = values.get(i);
//use val
}
Hopefully that makes sense.
map() takes a number in one linear system and maps it onto another linear system. Imagine if I were an evil professor and wanted to give students random grades from 0 to 100. I have a function that returns a random decimal between 0 and 1, so I can now do map(rand(),0,1,0,100); and it will convert the number for me! In this example, you could also just multiply by 100 and get the same result, but it is usually not so trivial. In this case, you have a sensor reading between 0 and 1500, but if you just plotted that value directly, sometimes it would go off the screen! So you have to scale it to an appropriate scale, which is what that does. 1500 is the max that the reading can be, and presumably we want the maximum graphing height to be at the edge of the screen.
I'm not familiar with your setup, but it looks like the readings can be negative, which means that they might get graphed off the screen, too. The better solution would be to map the readings from -1500,1500 to 0,height, but it looks like they chose to do it a different way. Whenever you call a drawing function in processing (eg point(x,y)), it draws the pixels at (x,y) offset from (0,0). Sometimes you don't want it to draw it relative to (0,0), so the translate() function allows you to change what it draws things relative against. In this case, translating allows you to plot some point (x,0) somewhere in the middle of the screen, rather than on the edge.
Hope that helps!

Method to combine multiple affine transforms as if each was specified in un-transformed space

I'm looking for a way to combine affine transforms in such a way so that the effect is equivalent to using each transform to manipulate a shape in succession. The problem is that if I simply concatenate the transforms, then each successive transform's effect is interpreted in the existing transform's co-ordinate space.
For example, consider a square around the origin (-50,-50, 100,100). I want to rotate it, and then translate it down 100px. If I take a transform and rotate and then translate, the translation gets interpreted in the rotated coordinates. Instead, if I transform the shape itself to rotate it, and then transform that shape again to translate it, both translations are interpreted in the "normal" un-translated plane, and it gives me what I want.
The problem is that for what I'm doing many transforms may take place, each of which needs to be interpreted in the normal coordinate plane, but I don't want to store a stack of transforms, nor can I simply keep manipulating a shape, because I need to at any time be able to create the final transformed shape from the original starting shape.
I'm aware that for this simple example if I did the translate before the rotate I'd get the same result, but that's missing the point. I'm dealing with an arbitrary set of successive scale, translate, and rotate transforms, so simply putting them in a certain order doesn't cut it.
I have an inkling that there should be a way to concatenate transforms in such a way that you modify the new transform before you concatenate it, correcting for the existing transform so that the effect is that the new transform appears to have been applied as if it were referencing the un-transformed coordinate plane. For example, if you translate by (70.7, 70.7) in the above example instead of (0,100), the result becomes equivalent. I just can't seem to figure out what the math is to figure out in general how to alter the new transform so it works out correctly.
Thanks for reading - hope this made sense. Heres the source of the example that created the screenshot:
public class TransformExample extends JPanel {
#Override
protected void paintComponent(Graphics _g) {
super.paintComponent(_g);
Graphics2D g = (Graphics2D) _g;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.translate(150, 100); // translate so we can see method 1 clearly
paintConcatenate(g);
g.translate(200, 0); // translate again so we can see method 2 to the right of method 1
paintSuccessive(g);
}
private void paintConcatenate(Graphics2D g) {
AffineTransform tx = new AffineTransform();
Shape shape = new Rectangle(-50, -50, 100, 100);
// Draw the 3 steps, altering the transform each time
draw(g, shape, tx, Color.GRAY);
tx.rotate(Math.PI / 4);
draw(g, shape, tx, Color.GREEN);
tx.translate(70.7, 70.7);
draw(g, shape, tx, Color.PINK);
}
private void paintSuccessive(Graphics2D g) {
Shape shape = new Rectangle(-50, -50, 100, 100);
// Draw the 3 steps, altering the shape each time with a new transform
draw(g, shape, null, Color.GRAY);
shape = AffineTransform.getRotateInstance(Math.PI / 4).createTransformedShape(shape);
draw(g, shape, null, Color.GREEN);
shape = AffineTransform.getTranslateInstance(0, 100).createTransformedShape(shape);
draw(g, shape, null, Color.PINK);
}
private void draw(Graphics2D g, Shape shape, AffineTransform tx, Color color) {
if (tx != null) {
shape = tx.createTransformedShape(shape);
}
g.setColor(color);
g.fill(shape);
}
public static void main(String[] args) {
JFrame f = new JFrame("Transform Example");
f.setSize(500, 350);
f.setContentPane(new TransformExample());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
(I'm working with Java2D, although I don't think the language or 2d library is all that pertinent here.)
I suggest you to keep track of some absolute values and then do less transformations as you can.
For example, store the translation matrix and the rotation angle around the origin.
int translate[2];
int rotate;
Now, suppose that you want to rotate around its center and then translate the object somewhere, and then rotate it again under its center.
Because with affine transformations, rotation matrix aren't commutative, so if you apply a rotation,translation, rotation you'll get an wrong result.
But you can simply sum the rotation angle of the first and third rotation, and apply a single rotation and then the translation.
Hope to be clear.
when you rotate an object, you normally rotate around a specific point. It looks like you are just rotating around (0,0) which is usually not what you want.
To rotate around a specific point (x,y),
translate the point to 0 (-x, -y),
then rotate,
then translate back (x, y).
public static AffineTransform getRotateInstance(double theta,
double anchorx,
double anchory)

Resources