Is there any other way to calculate X value in coords of other coord system? - algorithm

Sorry, for weird topic name, but I don't know how else to name it.
The problem is.. I have a zedgraph control. There is some lines drawn inside.
I have the coords of left border of chart area and right border of chart area.
I draw vertical lines as PictureBoxes over zedgraph control, so they moves in different coords. This vertical lines can be moved to left and right.
That way I trying to get X value in coords of XAxis:
public double Get_X_InContextOfChart(int left_coord_of_border) //Left of vertical line
{
//zed_graph.GraphPane.XAxis.Scale.Min is minimal X value shown on XAxis
//zed_graph.GraphPane.Chart.Rect.Left is Left of YAxis
//Same for else if, aside of using Right and maximum X at right
if (zed_graph.GraphPane.XAxis.Scale.Min != 0) //to avoid division by zero
return (left_coord_of_border * zed_graph.GraphPane.XAxis.Scale.Min) / zed_graph.GraphPane.Chart.Rect.Left;
else if (zed_graph.GraphPane.XAxis.Scale.Max != 0)
return (left_coord_of_border * zed_graph.GraphPane.XAxis.Scale.Max) / zed_graph.GraphPane.Chart.Rect.Right;
return double.NaN;
}
This code calculate X fine as long as else if used, but in my example it calculate something wrong.
I hope someone understand this.
Updated with new code:
public double Get_X_InContextOfChart(int left_coord_of_border)
{
double scale_left = zed_graph.GraphPane.XAxis.Scale.Min;
double scale_right = zed_graph.GraphPane.XAxis.Scale.Max;
double graph_width = zed_graph.GraphPane.Chart.Rect.Width;
double x = left_coord_of_border;
return scale_left + (scale_right - scale_left) / graph_width * x;
}
Result:

scale_left = -0.1
scale_right = 0.9
graph_width = 540 // pixels
x = 190 // pixels
scale_x = scale_left + (scale_right - scale_left) / graph_width * x // 0.25

Related

Move object around cube’s corner without jittering using accelerometer

I can move object (star) around cube’s corner using accelerometer. Object move following the orbit (green circle). Control inverted, if I tilt right object go left and vise versa.
While spinning cube around corner object move perfect. But when I stop spinning cube, object on one of the cube’s edges, cause of inverted control start jittering.
For example if I try to stop object between red and blue planes, it begins jumping from one plane to another.
Code for object movement
new accelX = abi_MTD_GetFaceAccelX(object.plane);
new accelY = abi_MTD_GetFaceAccelY(object.plane);
object.angle -= accelX - accelY;
if (object.angle >= 90) {
object.plane = GetRightPlane(object.plane);
object.angle -= 90;
} else if (object.angle <= 0) {
object.plane= GetBottomPlane(object.plane);
object.angle = 90 + spaceship.angle;
}
MovePointAlongCircle(OUT object.posX, OUT object.posY, object.orbit, object.angle);
Find coordinate on plane
const OBJECT _ORBIT_CENTER = 260;
new objectOrbit = 150;
MovePointAlongCircle(&posX, &posY, objectOrbit, anglePhi) {
posX = OBJECT_ORBIT_CENTER - (objectOrbit * cos(anglePhi));
posY = OBJECT _ORBIT_CENTER - (objectOrbit * sin(anglePhi));
}
I can get accelerometer values individually on each plane or like the cube is a one thing.
Trigonometric functions like sin and cos use fixed point and look up table.
I've got atan function, which return angle [-45; 45].
Atan(x) {
return ((PI_4_FIXED * x >> FP) - ((x * (ABS(x) - 256) >> FP) * (62 + (17 * ABS(x) >> FP)) >> FP)) * RAD_2_DEG >> FP;
}

recalibrate ball in pong so the edge hits first, not the centre in Processing

I've recently built a game of pong for a UNI assignment in Processing, but whenever the ball hits the top, bottom, side of the screen or the 'paddle' it only bounces back once half the ball is off the screen. I just want the edge of the ball to hit first rather than the centre, but am unsure where my code is going wrong. I hope this makes sense, I'm a definite beginner.
Here is my code for reference
//underwater pong
float x, y, speedX, speedY;
float diam = 10;
float rectSize = 200;
float diamHit;
PImage bg;
PImage img;
int z;
void setup() {
size(920, 500);
smooth();
fill(255);
stroke(255);
imageMode(CENTER);
bg = loadImage("underthesea.jpg");
img = loadImage("plastic.png");
reset();
}
void reset() {
x = width/2;
y = height/2;
//allows plastic to bounce
speedX = random(5, 5);
speedY = random(5, 5);
}
void draw() {
background(bg);
image(img, x/2, y);
rect(0, 0, 20, height);
rect(width/2, mouseY-rectSize/2, 50, rectSize);
//allows plastic to bounce
x += speedX;
y += speedY;
// if plastic hits movable bar, invert X direction
if ( x > width-30 && x < width -20 && y > mouseY-rectSize/2 && y < mouseY+rectSize/2 ) {
speedX = speedX * -1;
}
// if plastic hits wall, change direction of X
if (x < 25) {
speedX *= -1.1;
speedY *= 1.1;
x += speedX;
}
// if plastic hits up or down, change direction of Y
if ( y > height || y < 0 ) {
speedY *= -1;
}
}
void mousePressed() {
reset();
}
I wasn't able to run your code because I am missing the background and plastic images, but here's what's probably going wrong. I'm not 100% since I do not know the dimensions of your images either.
You are using imageMode(CENTER). See the documentation for details.
From the docs:
imageMode(CENTER) interprets the second and third parameters of image() as the image's center point. If two additional parameters are specified, they are used to set the image's width and height.
This treats the coordinates you input into the image function as the center of the image.
Your first issue is that you are placing your image at x/2 but doing all your collision checks with x in mind. x does not represent the middle of your image, because you're drawing it at x/2.
Then I'm not sure if you are doing your horizontal collision checks right, as you are checking against hardcoded values. I do know you are doing your vertical collision checks wrong. You are checking if the center of the image is at the top of the canvas, 0, or the bottom of the canvas, height. This means that your image will already have moved out of the screen halfway.
If you want to treat the image coordinates as the center of your image, you need to check the left edge of the image at x - imageWidth / 2, the right edge at X+ imageWidth / 2, the top edge at y - imageWidth / 2 (remember the y coordinates are 0 at the top of the canvas and increase towards the bottom) and the bottom at y - imageWidth / 2. Here's a great website which goes into more detail on 2d collision detection, i'd highly recommend you give it a read. It's an awesome website.

How do you zoom to bounding box using Xamarin Maps?

I have a Xamarin Android map (VS2019) and a number of lat/long points. What I want to do is have the map zoom in (or out), given a set of coordinates that set a bounding box.
I have this code (below) which doesn't seem to do anything. I've read all the documentation which suggests it should work but doesn't. I have checked and the bounding box coordinates are set correctly but the map doesn't do anything.
According to the docs calling LayOut should make it update but it doesn't do anything, no errors, just nothing.
How do I achieve this, any help would be much appreciated.
MyMap.Layout(GetBounds(points));
private Rectangle GetBounds(List<Point> points)
{
var minx = (from x in points select x.X).Min();
var maxx = (from x in points select x.X).Max();
var miny = (from x in points select x.Y).Min();
var maxy = (from x in points select x.Y).Max();
Rectangle rectangle = new Rectangle(minx, miny, maxx - minx, maxy - miny);
return rectangle;
}
Here's what I did
I created a rectangle with the bounds where I need them
Rectangle rectangle = GetBounds(points);
Then I got the rectangle location
Position p1 = new Position(rectangle.X, rectangle.Y);
Position p2 = new Position((rectangle.X + rectangle.Width), (rectangle.Y + rectangle.Height));
... and then got the center point of the rectangle
double x = rectangle.X + (rectangle.Width / 2);
double y = rectangle.Y + (rectangle.Height / 2);
Then called .MoveToRegion using that data, and it works
MyMap.MoveToRegion(
MapSpan.FromCenterAndRadius(
new Xamarin.Forms.Maps.Position(x, y), Distance.BetweenPositions(p1, p2))
);

Processing - creating circles from current pixels

I'm using processing, and I'm trying to create a circle from the pixels i have on my display.
I managed to pull the pixels on screen and create a growing circle from them.
However i'm looking for something much more sophisticated, I want to make it seem as if the pixels on the display are moving from their current location and forming a turning circle or something like this.
This is what i have for now:
int c = 0;
int radius = 30;
allPixels = removeBlackP();
void draw {
loadPixels();
for (int alpha = 0; alpha < 360; alpha++)
{
float xf = 350 + radius*cos(alpha);
float yf = 350 + radius*sin(alpha);
int x = (int) xf;
int y = (int) yf;
if (radius > 200) {radius =30;break;}
if (c> allPixels.length) {c= 0;}
pixels[y*700 +x] = allPixels[c];
updatePixels();
}
radius++;
c++;
}
the function removeBlackP return an array with all the pixels except for the black ones.
This code works for me. There is an issue that the circle only has the numbers as int so it seems like some pixels inside the circle won't fill, i can live with that. I'm looking for something a bit more complex like I explained.
Thanks!
Fill all pixels of scanlines belonging to the circle. Using this approach, you will paint all places inside the circle. For every line calculate start coordinate (end one is symmetric). Pseudocode:
for y = center_y - radius; y <= center_y + radius; y++
dx = Sqrt(radius * radius - y * y)
for x = center_x - dx; x <= center_x + dx; x++
fill a[y, x]
When you find places for all pixels, you can make correlation between initial pixels places and calculated ones and move them step-by-step.
For example, if initial coordinates relative to center point for k-th pixel are (x0, y0) and final coordinates are (x1,y1), and you want to make M steps, moving pixel by spiral, calculate intermediate coordinates:
calc values once:
r0 = Sqrt(x0*x0 + y0*y0) //Math.Hypot if available
r1 = Sqrt(x1*x1 + y1*y1)
fi0 = Math.Atan2(y0, x0)
fi1 = Math.Atan2(y1, x1)
if fi1 < fi0 then
fi1 = fi1 + 2 * Pi;
for i = 1; i <=M ; i++
x = (r0 + i / M * (r1 - r0)) * Cos(fi0 + i / M * (fi1 - fi0))
y = (r0 + i / M * (r1 - r0)) * Sin(fi0 + i / M * (fi1 - fi0))
shift by center coordinates
The way you go about drawing circles in Processing looks a little convoluted.
The simplest way is to use the ellipse() function, no pixels involved though:
If you do need to draw an ellipse and use pixels, you can make use of PGraphics which is similar to using a separate buffer/"layer" to draw into using Processing drawing commands but it also has pixels[] you can access.
Let's say you want to draw a low-res pixel circle circle, you can create a small PGraphics, disable smoothing, draw the circle, then render the circle at a higher resolution. The only catch is these drawing commands must be placed within beginDraw()/endDraw() calls:
PGraphics buffer;
void setup(){
//disable sketch's aliasing
noSmooth();
buffer = createGraphics(25,25);
buffer.beginDraw();
//disable buffer's aliasing
buffer.noSmooth();
buffer.noFill();
buffer.stroke(255);
buffer.endDraw();
}
void draw(){
background(255);
//draw small circle
float circleSize = map(sin(frameCount * .01),-1.0,1.0,0.0,20.0);
buffer.beginDraw();
buffer.background(0);
buffer.ellipse(buffer.width / 2,buffer.height / 2, circleSize,circleSize);
buffer.endDraw();
//render small circle at higher resolution (blocky - no aliasing)
image(buffer,0,0,width,height);
}
If you want to manually draw a circle using pixels[] you are on the right using the polar to cartesian conversion formula (x = cos(angle) * radius, y = sin(angle) * radius).Even though it's focusing on drawing a radial gradient, you can find an example of drawing a circle(a lot actually) using pixels in this answer

Quaternion translation and rotation in iOS OpenGL ES

I'm struggling with some quaternion code in iOS. I have an open cube, which i've rotated into an isometric view. i am able to rotate the cube with touch and rotate about its axis and also zoom in/out. I also have labels associated with the cube - which also need to rotate with the cube. Again, i've managed to do this.
However, i'm now trying to implement being able to drag the label (ie. translate it) from one position, to another. If we look at the image below, what i've tried to illustrate is that i want to be able to translate the label from "label from" to the position "label to". Then, when i come to rotating the cube, the label should stay in its new position and rotate with the cube. However, i'm making a cock-up of this translation and when i try rotating the cube, the label jumps to a new position since i've not set the label coordinates properly.
I have the quaternion associated with the cube.
With the following code, i have been able to translate the label properly when the quaternion is set to [0, 0, 0, 1] (so that the cube is front-on - looks like a square from this position).
- (void) rotateWithAngle:(float) radians andVector:(GLKVector3) axis andScale:(float) scale
{
if (radians != self.lastRadians
|| (axis.v[0] != self.lastAxis.v[0] || axis.v[1] != self.lastAxis.v[1] || axis.v[2] != self.lastAxis.v[2])
|| scale != self.lastScale)
{
GLKMatrix4 m = GLKMatrix4MakeTranslation(self.normX, self.normY, self.normZ);
if (radians != 0)
m = GLKMatrix4Rotate(m, radians, axis.x, -axis.y, axis.z);
m = GLKMatrix4Scale(m, scale, scale, scale);
float x = (m.m00 * m.m30) + (m.m01 * m.m31) + (m.m02 * m.m32) + (m.m03 * m.m33);
float y = (m.m10 * m.m30) + (m.m11 * m.m31) + (m.m12 * m.m32) + (m.m13 * m.m33);
float z = (m.m20 * m.m30) + (m.m21 * m.m31) + (m.m22 * m.m32) + (m.m23 * m.m33);
x /= m.m33;
y /= m.m33;
z /= m.m33;
float w = (((x+self.winSz) / (self.winSz * 2.0)) * self.parentFrame.size.width) + self.parentFrame.origin.x;
float h = (((y+self.winSz) / (self.winSz * 2.0)) * self.parentFrame.size.height) + self.parentFrame.origin.y;
self.lastRadians = radians;
self.lastAxis = axis;
self.lastScale = scale;
[self setCenter:CGPointMake(w,h)];
}
}
- (void) translateFromTouch:(UIPanGestureRecognizer *) pan
{
CGPoint translation = [pan translationInView:self];
CGPoint imageViewPosition = self.center;
GLKVector3 axis = GLKQuaternionAxis(*_quaternion);
float rot = GLKQuaternionAngle(*_quaternion);
CGFloat h = self.parentFrame.size.height;
CGFloat w = self.parentFrame.size.width;
imageViewPosition.x += translation.x;
imageViewPosition.y += translation.y;
self.center = imageViewPosition;
// recalculate the norm position
float x = ((2.0 * self.winSz * (imageViewPosition.x - self.parentFrame.origin.x)) / w) - self.winSz;
float y = ((2.0 * self.winSz * (imageViewPosition.y - self.parentFrame.origin.y)) / h) - self.winSz;
self.normX = x;
self.normY = y;
[pan setTranslation:CGPointZero inView:self];
}
These methods are hit if a label (based on a UILabel) is either dragged or the cube (or the opengl scene) is rotated.
This works when we are looking front-on, so that the x,y values can easily be converted from pixel coords into normal or world coords.
However, when the axis is not front-on, i'm struggling to figure it out. For instance, we we have the quaternion set at (0, sqrt(2)/2, 0, sqrt(2)/2) then all x translations correspond to z world coords. So how do i make this connection/calculation? I'm sure it's fairly easy but i've hit a wall with this.
(winSz i have set to 1.5. model coords very between -1 and 1)

Resources