Move a 2d point to a target point with certain speed through x or y axis - point

Given that moving a point A(x1,y1) to location (x2,y2) with a fixed speed, say 3 units(points) per sec.
The requirement is that the point A can only moves through x or y axis.
For example, A(0,0) moves to target(10,10) at 3units/sec. First starting move on x axis, after 1s, location of A becomes (3,0). Then becomes (9,0) after 3s. Now on the x axis, the A only needs to move 1 more unit and then move 2 units on the y axis, which becomes (10,2), then continue on the y axis, (10,5)...(10,8)
My question is: Is there any efficient way to achieve this? This is my logic:
while(the point is not arriving the target point) {
currentX = SourceX;
currentY = SourceY;
differenceOnXaxis=TargetX-currentX;
differenceOnYaxis=TargetY-currentY;
if(differenceOnXaxis == 0) {
if(differenceOnYaxis == 0) {
//Arrive at the target point
} else if (differenceOnYaxis >= MovingUnit){
currentY += MovingUnit;
} else if (0 <differenceOnYaxis < MovingUnit){
currentY += differenceOnYaxis;
} else if (-MovingUnit <differenceOnYaxis < 0) {
currentY += differenceOnYaxis;
} else if (differenceOnYaxis<= (-MovingUnit)) {
currentY -= MovingUnit;
}
} else if(differenceOnXaxis >= MovingUnit){
currentX += moving unit;
} else if (0< differenceOnXaxis < MovingUnit) {
currentX += differenceOnXaxis;
if(differenceOnYaxis > 0){
currentY += (MovingUnit - differenceOnXaxis)
} else if (differenceOnYaxis < 0) {
currentY += -(MovingUnit-differenceOnXaxis)
}
} else if (- MovingUnit < differenceOnXaxis < 0) {
currentX += differenceOnXaxis;
} else if (differenceOnXaxis <= (-MovingUnit)) {
currentX -= MovingUnit;
}
}

Related

CS50 Credit: Always getting INVALID return

Was attempting Credit from CS50 and kept getting INVALID return from my code. I approached this problem by using arrays even though it may not have been the best method. Code compiles with no issues.
My pseudocode logic was:
1) obtain card number
2) use loop to find number of digits
3) check if card contains 13, 15 or 16 digits
4) if so, write digits from long into array
5) have a copy of original array to multiply every other number by 2
6) add the digits of the product
7) check for card length and starting digits
Here is my code:
#include <stdio.h>
#include <cs50.h>
int main(void)
{
// Get credit card number
long num = get_long("Number: ");
// Find number of digits
int digits = 0;
while (num > 0)
{
num /= 10;
digits++;
}
// Check if number of digits is within possible range
if (digits != 13 && digits != 15 && digits != 16)
{
printf("INVALID\n");
}
int originalnumber[digits];
// Write each digit of credit card number into an array
for (int i = digits - 1; i >= 0; i--)
{
originalnumber[i] = num % 10;
num = num / 10;
}
// Multiply alternate digits by 2
int number[digits];
for (int i = 0; i < digits; i++)
{
number[i] = originalnumber[i];
}
for (int i = 1; i < digits; i+=2)
{
number[i] = number[i] * 2;
}
// Add product digits
int sum = 0;
int temp;
for (int i = 0; i < digits; i++)
{
temp = (number[i] % 10) + ((number[i] / 10) % 10);
sum = sum + temp;
}
// Check for card length and starting digits
// AMEX
if (digits == 15)
{
if (originalnumber[14] == 3 && sum % 10 == 0 && (originalnumber[13] == 4 || originalnumber[13] == 7))
{
printf("AMEX\n");
return 0;
}
}
// MasterCard
if (digits == 16)
{
if (originalnumber[15] == 5 && sum % 10 == 0 && (originalnumber[14] == 1 || originalnumber[14] == 2 || originalnumber[14] == 3 || originalnumber[14] == 4 || originalnumber[14] == 5))
{
printf("MASTERCARD\n");
return 0;
}
}
// Visa
if (digits == 13)
{
if (originalnumber[12] == 4 && sum % 10 == 0)
{
printf("VISA\n");
return 0;
}
}
if (digits == 16)
{
if (originalnumber[15] == 4 && sum % 10 == 0)
{
printf("VISA\n");
return 0;
}
}
printf("INVALID\n");
return 1;
}
I tried debug50 and it seems that when I try to sum the digits together using temp and sum, the loop completes with sum still being 0. May I know what is wrong here? Is the flow of my pseudocode wrong or are there any glaring mistakes that I may have overlooked? (stared at this for way too long..)
Thank you in advance!
If sum is always 0, regardless of whether that is what you expect, sum % 10 would always be 0, so that is not the "false" that is failing the tests.
Which should direct your attention to originalnumber.
What is the value of num after this loop?
while (num > 0)
{
num /= 10;
digits++;
}

Add anti-aliasing/bandlimit for looped wav sample (NOT Fourier transform)

How to build antialiasing interpolation using c++ code? I have a simple 4096 or 1024 buffer. Of course when I play this at high frequencies I get aliasing issues. to avoid this, the signal must be limited by the bandwidth at high frequencies. Roughly speaking, the 'sawtooth' wave at high frequencies should looks like a regular sine. And that is what I want to get so that my sound didn't sound dirty like you moving knobs in your old FM/AM radio in your car.
I know how to build bandlimited square,triangle,sawtoth with Fourier transform. So my question is only about wavetable
Found solution in the AudioKit sources. One buffer will be split into 10 buffers/octaves. So when you play a sound, you don't play your original wave, but play a sample that was prepared for a specific octave.
Import to your project WaveStack.hpp
namespace AudioKitCore
{
// WaveStack represents a series of progressively lower-resolution sampled versions of a
// waveform. Client code supplies the initial waveform, at a resolution of 1024 samples,
// equivalent to 43.6 Hz at 44.1K samples/sec (about 23.44 cents below F1, midi note 29),
// and then calls initStack() to create the filtered higher-octave versions.
// This provides a basis for anti-aliased oscillators; see class WaveStackOscillator.
struct WaveStack
{
// Highest-resolution rep uses 2^maxBits samples
static constexpr int maxBits = 10; // 1024
// maxBits also defines the number of octave levels; highest level has just 2 samples
float *pData[maxBits];
WaveStack();
~WaveStack();
// Fill pWaveData with 1024 samples, then call this
void initStack(float *pWaveData, int maxHarmonic=512);
void init();
void deinit();
float interp(int octave, float phase);
};
}
WaveStack.cpp
#include "WaveStack.hpp"
#include "kiss_fftr.h"
namespace AudioKitCore
{
WaveStack::WaveStack()
{
int length = 1 << maxBits; // length of level-0 data
pData[0] = new float[2 * length]; // 2x is enough for all levels
for (int i=1; i<maxBits; i++)
{
pData[i] = pData[i - 1] + length;
length >>= 1;
}
}
WaveStack::~WaveStack()
{
delete[] pData[0];
}
void WaveStack::initStack(float *pWaveData, int maxHarmonic)
{
// setup
int fftLength = 1 << maxBits;
float *buf = new float[fftLength];
kiss_fftr_cfg fwd = kiss_fftr_alloc(fftLength, 0, 0, 0);
kiss_fftr_cfg inv = kiss_fftr_alloc(fftLength, 1, 0, 0);
// copy supplied wave data for octave 0
for (int i=0; i < fftLength; i++) pData[0][i] = pWaveData[i];
// perform initial forward FFT to get spectrum
kiss_fft_cpx spectrum[fftLength / 2 + 1];
kiss_fftr(fwd, pData[0], spectrum);
float scaleFactor = 1.0f / (fftLength / 2);
for (int octave = (maxHarmonic==512) ? 1 : 0; octave < maxBits; octave++)
{
// zero all harmonic coefficients above new Nyquist limit
int maxHarm = 1 << (maxBits - octave - 1);
if (maxHarm > maxHarmonic) maxHarm = maxHarmonic;
for (int h=maxHarm; h <= fftLength/2; h++)
{
spectrum[h].r = 0.0f;
spectrum[h].i = 0.0f;
}
// perform inverse FFT to get filtered waveform
kiss_fftri(inv, spectrum, buf);
// resample filtered waveform
int skip = 1 << octave;
float *pOut = pData[octave];
for (int i=0; i < fftLength; i += skip) *pOut++ = scaleFactor * buf[i];
}
// teardown
kiss_fftr_free(inv);
kiss_fftr_free(fwd);
delete[] buf;
}
void WaveStack::init()
{
}
void WaveStack::deinit()
{
}
float WaveStack::interp(int octave, float phase)
{
while (phase < 0) phase += 1.0;
while (phase >= 1.0) phase -= 1.0f;
int nTableSize = 1 << (maxBits - octave);
float readIndex = phase * nTableSize;
int ri = int(readIndex);
float f = readIndex - ri;
int rj = ri + 1; if (rj >= nTableSize) rj -= nTableSize;
float *pWaveTable = pData[octave];
float si = pWaveTable[ri];
float sj = pWaveTable[rj];
return (float)((1.0 - f) * si + f * sj);
}
}
Then use it in this way:
//wave and outputWave should be float[1024];
void getSample(int octave, float* wave, float* outputWave){
uint_fast32_t impulseCount = 1024;
if (octave == 0){
impulseCount = 737;
}else if (octave == 1){
impulseCount = 369;
}
else if (octave == 2){
impulseCount = 185;
}
else if (octave == 3){
impulseCount = 93;
}
else if (octave == 4){
impulseCount = 47;
}
else if (octave == 5){
impulseCount = 24;
}
else if (octave == 6){
impulseCount = 12;
}
else if (octave == 7){
impulseCount = 6;
}
else if (octave == 8){
impulseCount = 3;
}
else if (octave == 9){
impulseCount = 2;
}
//Get sample for octave
stack->initStack(wave, impulseCount);
for (int i = 0; i < 1024;i++){
float phase = (1.0/float(1024))*i;
//get interpolated wave and apply volume compensation
outputWave[i] = stack->interp(0, phase) / 2.0;
}
}
Then... when 10 buffers is ready. You can use them when playing a sound. Using this code you can get index of buffer/octave depending to your frequency
uint_fast8_t getBufferIndex(const float& frequency){
if (frequency >= 0 && frequency < 40){
return 0;
}
else if (frequency >= 40 && frequency < 80){
return 1;
}else if (frequency >= 80 && frequency < 160){
return 2;
}else if (frequency >= 160 && frequency < 320){
return 3;
}else if (frequency >= 320 && frequency < 640){
return 4;
}else if (frequency >= 640 && frequency < 1280){
return 5;
}else if (frequency >= 1280 && frequency < 2560){
return 6;
}else if (frequency >= 2560 && frequency < 5120){
return 7;
}else if (frequency >= 5120 && frequency < 10240){
return 8;
}else if (frequency >= 10240){
return 9;
}
return 0;
}
So if I know that my note frequency 440hz. Then for this note I'm getting wave in this way:
float notInterpolatedSound[1024];
float interpolatedSound[1024];
uint_fast8_t octaveIndex = getBufferIndex(440.0);
getSample(octaveIndex, notInterpolatedSound, interpolatedSound);
//tada!
ps. the code above is a low pass filter. I also tried to do sinc interpolation. But sinc worked for me very expensive and not exactly. Although maybe I did it wrong.

I want to track 2 colours, but only record the movement of those two colours and hide the video feed

For context: I am going to analyze the breathing movement of parents during kangaroo mother care and I wish to respect their privacy by not recording them, but only the movement of stickers I placed on their chest and stomach.
So far, I'm able to track 2 colours based on webcam input through the code below. However, I would like to record only the tracked colours instead of the webcam feed as to preserve the privacy of the parent.
Does anybody know how to add a background colour, whilst still being able to track colour?
import processing.video.*;
Capture video;
final int TOLERANCE = 20;
float XRc = 0;// XY coordinate of the center of the first target
float YRc = 0;
float XRh = 0;// XY coordinate of the center of the second target
float YRh = 0;
int ii=0; //Mouse click counter
color trackColor; //The first color is the center of the robot
color trackColor2; //The second color is the head of the robot
void setup() {
size(640,480);
video = new Capture(this,640,480);
video.start();
trackColor = color(255,0,0);
trackColor2 = color(255,0,0);
smooth();
}
void draw() {
background(0);
if (video.available()) {
video.read();
}
video.loadPixels();
image(video,0,0);
float r2 = red(trackColor);
float g2 = green(trackColor);
float b2 = blue(trackColor);
float r3 = red(trackColor2);
float g3 = green(trackColor2);
float b3 = blue(trackColor2);
int somme_x = 0, somme_y = 0;
int compteur = 0;
int somme_x2 = 0, somme_y2 = 0;
int compteur2 = 0;
for(int x = 0; x < video.width; x++) {
for(int y = 0; y < video.height; y++) {
int currentLoc = x + y*video.width;
color currentColor = video.pixels[currentLoc];
float r1 = red(currentColor);
float g1 = green(currentColor);
float b1 = blue(currentColor);
if(dist(r1,g1,b1,r2,g2,b2) < TOLERANCE) {
somme_x += x;
somme_y += y;
compteur++;
}
else if(compteur > 0) {
XRc = somme_x / compteur;
YRc = somme_y / compteur;
}
if(dist(r1,g1,b1,r3,g3,b3) < TOLERANCE) {
somme_x2 += x;
somme_y2 += y;
compteur2++;
}
else if(compteur2 > 0) {
XRh = somme_x2 / compteur2;
YRh = somme_y2 / compteur2;
}
}
}
if(XRc != 0 || YRc != 0) { // Draw a circle at the first target
fill(trackColor);
strokeWeight(0.05);
stroke(0);
ellipse(XRc,YRc,20,20);
}
if(XRh != 0 || YRh != 0) {// Draw a circle at the second target
fill(trackColor2);
strokeWeight(0.05);
stroke(0);
ellipse(XRh,YRh,20,20);
}
}
void mousePressed() {
if (mousePressed && (mouseButton == RIGHT)) { // Save color where the mouse is clicked in trackColor variable
if(ii==0){
if (mouseY>480){mouseY=0;mouseX=0;}
int loc = mouseX + mouseY*video.width;
trackColor = video.pixels[loc];
ii=1;
}
else if(ii==1){
if (mouseY>480){mouseY=0;mouseX=0;}
int loc2 = mouseX + mouseY*video.width;
trackColor2 = video.pixels[loc2];
ii=2;
}
}
}
Try adding the background(0); right before you draw the first circle. It should cover the video and you can draw the circles on top of it.
Regards
Jose

OpenMPI breaking out of a loop

I'm having a hard time figuring out how to break out of a loop using OpenMPI in c.
Here's my loop
for( i=1; i<=steps;i++) {
do_calculation(psi,new_psi,&mydiff,i1,i2,j1,j2);
if (breakNow == 1) {
break;
}
diff = find_difference();
if(myid == mpi_master && i % iout == 0){
printf("%8d %15.5f\n",i,diff);
if (diff == 0.00) {
printf("DONE!");
breakNow = 1;
MPI_Bcast(&breakNow, 1, MPI_INT, mpi_master, MPI_COMM_WORLD);
}
}
}
I need to break all of the processors out of the loop when there is a difference of 0.00 but it seems like the breakNow variable isn't being broadcast to all the processors. Am I missing something?
MPI_Bcast is a collective operation. You need to call it in all processes in order for it to complete. In the process whose rank matches mpi_root the broadcast will behave like a send operation and in all other ranks it will behave as a receive operation.
Just move the call to MPI_Bcast outside of the conditional. May be the right place is just before the if (breakNow == 1) break; line.
Another suggestion: if find_difference returns the same value in all processes, you can do something similar to:
for (i = 1; i <= steps; i++) {
do_calculation(psi, new_psi, &mydiff, i1, i2, j1, j2);
diff = find_difference();
if (i % iout == 0) {
if (myid == mpi_master) {
printf("%8d %15.5f\n", i, diff);
if (diff == 0.00)
printf("DONE!");
}
if (diff == 0.00) break;
}
}
If find_difference only gives meaningful results in the master process, then modify as follows:
for (i = 1; i <= steps; i++) {
do_calculation(psi, new_psi, &mydiff, i1, i2, j1, j2);
diff = find_difference();
if (i % iout == 0) {
if (myid == mpi_master) {
printf("%8d %15.5f\n", i, diff);
if (diff == 0.00)
printf("DONE!");
}
MPI_Bcast(&diff, 1, MPI_DOUBLE, mpi_master, MPI_COMM_WORLD);
if (diff == 0.00) break;
}
}
(I have assumed that diff is of type double and preserved the original semantics of your code to check for zero difference once every iout steps)

Conways's Game of life array problems

I'm writing a Conway's life game for school. In the program I am having trouble with the arrays taking the values I am assigning them. At one point in the program they print out the value assigned to them (1) yet at the end of the program when I need to print the array to show the iterations of the game it shows an incredibly low number. The other trouble was I was encountering difficulties when putting in a loop that would ask if it wants you to run another iteration. So I removed it until the previous errors were fixed.
Im writing this with C++
#include <stdio.h>
int main (void)
{
int currentarray [12][12];
int futurearray [12][12];
char c;
char check = 'y';
int neighbors = 0;
int x = 0; // row
int y = 0; //column
printf("Birth an organism will be born in each empty location that has exactly three neighbors.\n");
printf("Death an organism with four or more organisms as neighbors will die from overcrowding.\n");
printf("An organism with fewer than two neighbors will die from loneliness.\n");
printf("Survival an organism with two or three neighbors will survive to the next generation.\n");
printf( "To create life input x, y coordinates.\n");
while ( check == 'y' )
{
printf("Enter x coordinate.\n");
scanf("%d", &x ); while((c = getchar()) != '\n' && c != EOF);
printf("Enter y coordinate.\n");
scanf("%d", &y ); while((c = getchar()) != '\n' && c != EOF);
currentarray [x][y] = 1;
printf ("%d\n", currentarray[x][y]);
printf( "Do you wish to enter more input? y/n.\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
}
// Note - Need to add a printf statement showing the array before changes are made after input added.
// check for neighbors
while(check == 'y')
{
for(y = 0; y <= 12; y++)
{
for(x = 0; x <= 12; x++)
{
//Begin counting number of neighbors:
if(currentarray[x-1][y-1] == 1) neighbors += 1;
if(currentarray[x-1][y] == 1) neighbors += 1;
if(currentarray[x-1][y+1] == 1) neighbors += 1;
if(currentarray[x][y-1] == 1) neighbors += 1;
if(currentarray[x][y+1] == 1) neighbors += 1;
if(currentarray[x+1][y-1] == 1) neighbors += 1;
if(currentarray[x+1][y] == 1) neighbors += 1;
if(currentarray[x+1][y+1] == 1) neighbors += 1;
//Apply rules to the cell:
if(currentarray[x][y] == 1 && neighbors < 2)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && neighbors > 3)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && (neighbors == 2 || neighbors == 3))
futurearray[x][y] = 1;
else if(currentarray[x][y] == 0 && neighbors == 3)
futurearray[x][y] = 1;
}
}
}
// Set the current array to the future and change the future to 0
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
}
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//print the current life board
printf("%d ", currentarray[x][y]);
}
}
}
// Have gone through one iteration of Life
//Ask to do another iteration
printf("Do you wish to continue y/n?\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
return 0;
}
You are defining your arrays as [12][12].
In your generation loop you walk from i = 0 to i <= 12, which is 13 steps instead of the 12 of the array. Additionally you are trying to access x-1 and y-1, which can be as low as -1. Again not inside your array.
Sometimes you get semi-useful values from within your array, but on some borders you are just accessing random data.
Try to correct your border.
You forgot to set neighbors to 0 before counting them.
Since this is C++ (not C), you might as well declare neighbors inside the loop body. Makes these kinds of issues easier to spot, too.
Also, is it me, or is that while loop never going to finish? Your braces are a mess, in general, as is your indentation. You could do yourself and us a favour by cleaning those up.
Obviously agree with all the above suggestions. One nice trick you might want to implement with Life is to create an extra border around your area. So if the user wants a 12x12 grid (and you should allow width/height to be specified and allocate memory dynamically) internally you hold a 14x14 grid corresponding to a border around the actual grid. Before running the calculation copy the top row to the bottom border, bottom row to the top border etc. Now you can run the main algorithm on the inner 12x12 grid without worrying about edge cases. This will enable your patterns to re-appear on the other side if they fall off the edge.
You're also forgetting to set the values of both arrays to zero. This will take care of the ridiculous number issue you're having. you can do that by copying this for loop:
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
and pasting it before the while loop but instead of setting currentarray[x][y] = futurearray[x][y], set it to 0. Also, if the coordinates are viewable locations instead of array co-ordinates, you'll want to change this:
printf ("%d\n", currentarray[x][y]);
to this:
printf ("%d\n", currentarray[x-1][y-1]);
I would also recommend putting a printf with a newline (\n) after each row has been printed and a tab (\t) after each item so that the formatting looks cleaner.

Resources