I want to calculate a point on a line by the distance to the first point.
Because I dont have any coordinates of the new point, i can't use the linear interpolation...
I thought like this:
Example Drawing
(Sorry, I'm a new user and I am not allowed to post images)
But actually it doesnt work, so I ask you for help.
Here is the actual code in java:
public static PointDouble interpolationByDistance(Line l, double d) {
double x1 = l.p1.x, x2 = l.p2.x;
double y1 = l.p1.y, y2 = l.p2.y;
double ratioP = ratioLine_x_To_y(l);
double disP = l.p1.distance(l.p2);
double ratioDis = d / disP;
PointDouble pn = l.p2.getLocation();
pn.multi(ratioDis);
System.out.println("dis: " + d);
System.out.println("new point dis: " + l.p1.distance(pn));
return pn;
}
Thank you.
As a programmer you should love changing a problem to a one you have already solved. Find the ratio and then use the linear interpolation:
public static PointDouble interpolationByDistance(Line l, double d) {
double len = l.p1.distance(l.p2);
double ratio = d/len;
double x = ratio*l.p2.x + (1.0 - ratio)*l.p1.x;
double y = ratio*l.p2.y + (1.0 - ratio)*l.p1.y;
System.out.println(x + ", " + y);
...
}
The basics of this are quite simple:
f = 0.3;
xp = f * x1 + (1-f) * x2;
yp = f * y1 + (1-f) * y2;
To understand this, consider:
if f==0, then xp = x2, yp=y2
if f==1, then xp = x1, yp=y1
for any value of f between 0..1, you get a point between (x1,y1)..(x2,y2)
I'm not sure what you exactly intend to calculate. This takes a value f in the range 0..1. If you have d as an absolute length, do f=d/disP
Related
I'm working on an assignment to write a java program which implements a Point data type with the following constructor:
Point(double x, double y, double z)
and, the following API:
double distanceto(Point q)
it returns the Euclidean distance between this and q.
The Euclidean distance between (x1, y1, z1) and (x2, y2, z2) is defined as sqrt( (x1-x2)^2 + (y1-y2)^2) + (z1-z2)^2).
String toString() – it returns the string representation of the point. An example would be (2.3,4.5,3.0).
Write a main method in the class that is used to test it.
It should create two Point objects using input provided by the user on the command-line.
Then it should print out the two points followed by their Euclidean distance
A sample run would be as follows.
java Point 2.1 3.0 3.5 4 5.2 3.5
The first point is (2.1,3.0,3.5)
The second point is (4.0,5.2,3.5)
Their Euclidean distance is 2.90
The program won't compile, but I'm not sure why. I'm new to programming, so I followed some steps from online and Codecademy to try and access objects in the constructor, but I think I'm doing it wrong. Any suggestions would be greatly appreciated.
public class Point {
double x1;
double y1;
double z1;
double x2;
double y2;
double z2;
public Point(double x, double y, double z){
x1 = x;
y1 = y;
z1 = z;
x2 = x;
y2 = y;
z2 = z;
}
public double distanceTo(Point q){
return Math.sqrt(Math.pow((x1-x2), 2.0) + Math.pow((y1-y2), 2.0) + Math.pow((z1-z2), 2.0));
}
double x3 = x1-x2;
double y3 = y1-y2;
double z3 = z1-z2;
public String toString() {
return "(" + x3 + ", " + y3 + ", " + z3 + ")";
}
public static void main (String[]args){
Point pointOne = new Point(args[0]);
Point pointTwo = new Point(args[1]);
Point distance = new distanceTo();
System.out.println("The first point is " + "(" + pointOne + ")");
System.out.println("The second point is " + "(" + pointTwo + ")");
System.out.println("Their Euclidean distance is " + distance);
}
}
A couple of things:
First, you should only need one set of variables for your Point class. Just make one set and construct two point objects.
In the distanceTo() method, access the other point's coordinates by doing q.x1, q.y1, and so on.
In the main method, distance should be double that's pointOne's distance to pointTwo.
Here's the code that worked for me
class Point {
double x1;
double y1;
double z1;
public Point(double x, double y, double z){
//each point object only needs one x, y and z
x1 = x;
y1 = y;
z1 = z;
}
public double distanceTo(Point pointTwo){
return Math.sqrt(Math.pow(pointTwo.x1-x1, 2.0) + Math.pow(pointTwo.y1-y1, 2.0) + Math.pow(pointTwo.z1-z1, 2.0));
//formula is sqrt((p2.x-p1)^2 + (p2.y-p1.y)^2 + (p2.z - p1.z)^2
}
public String toString() {
return "(" + x1 + ", " + y1 + ", " + z1 + ")";
//we don't need a diff set of variables here
}
public static void main (String[]args){
//make two diff points with coords
Point pointOne = new Point(2.1, 3.0, 3.5);
Point pointTwo = new Point(4.0,5.2, 3.5);
double distance = pointOne.distanceTo(pointTwo);
//uses point two as the parameter (x2, y2, z2 in formula)
System.out.println("The first point is " + "(" + pointOne + ")");
System.out.println("The second point is " + "(" + pointTwo + ")");
System.out.println("Their Euclidean distance is " + distance);
}
}
Been stuck on this for awhile even though there's probably an easy solution.
Given two points:
P1 = (5,5) and P2 = (6,10)
The distance between these two points D = 5.1
Is it possible to find the coordinates of where the third vertex would need to go to make an isosceles right triangle with either point?
Anyone able to help?
Is this right?
double ax = 5;
double ay = 5;
double bx = 6;
double by = 10;
// Vector of A > B
double abx = bx - ax;
double aby = by - ay;
// Rotate 90 degrees to get Vector B > C
double n = Math.toRadians(90.0);
double rx = (abx * Math.cos(n)) - (aby * Math.sin(n));
double ry = (abx * Math.sin(n)) + (aby * Math.cos(n));
// Point B + Vector B > C
double cx = bx + rx;
double cy = by + ry;
Ending with P3 = (1, 11)
Here's a hint:
As #f1sh said, there are 6 points (in red). In the image, I've rotated your line for easier representation, so you can rotate it back and see what results you should be getting.
The following code is called every 50ms.
// Start point
private double x;
private double y;
private double z;
private double y1;
#Override
public void run() {
double x1 = Math.cos(y1);
double z1 = Math.sin(y1);
double y2 = 4D - y1;
double x2 = Math.sin(y2);
double z2 = Math.cos(y2);
// First new point
double pX1 = x + x1;
double pY1 = y + y1;
double pZ1 = z + z1;
// Second new point
double pX2 = x + x2;
double pY2 = y + y2;
double pZ2 = z + z2;
if (y1 > 4D) {
y1 = 0D;
} else {
y1 = y1 + 0.1D;
}
}
Here is the output in a game. It generates two helices.
I cannot control more than the radius.
I am looking for code I can easily customize to fit my preferences.
How do I control the following aspects?
How fast the helix rises.
Where the helix begins.
helix is circular shape with 'linear' movement of the plane
you use plane xz as helix base and y axis as height
so you need:
r - radius
d - distance between two screws (the y movement after full circle)
t - parameter <0,1> determining the position on helix
h0,h1 - start end height of helix (y-axis)
a0 - angular start position [rad]
Now how to get the point on helix as function of parameter these parameters
aa=fabs(h1-h0)*2.0*M_PI/d; // angular speed coefficient
// if you need opposite angular direction then add aa=-aa;
x=r*cos(a0+aa*t);
z=r*sin(a0+aa*t);
y=h0+((h1-h0)*t);
aa can be precomputed once
now if t=0.0 then you get the start point of helix
if t=1.0 then you got the endpoint of helix
so speed is just how much you add to t during animation per timer cycle
d controls number of screw loops
h1-h0 is the helix height
code is in C++ (sorry I am not a JAVA coder)
One part of the helix begins at:
(x, y, z) = (1.0, 0.0, 0.0)
And the other at:
(x, y, z) = (-0.8, 4.0, -0.7)
And the particle rises at a rate of 0.1 (from y1 = y1 + 0.1D).
So, to control how fast the particles rise, just change this value.
To control where the helix begins you need to change the angle. For example, add some value to the sines and cosines. Like this:
Math.cos(y1 + dy);
To make more rotations before restarting from the ground you can multiply the angle. Make it twice as fast:
Math.cos(2 * y1);
Helix is circular shape with progressive Y value.
// Start point
private double x;
private double y;
private double z;
private double degree;
private double rY;
#Override
public void run() {
// We use the same formula that is used to find a point of a circumference
double rX = Math.cos(degree);
double rZ = Math.sin(degree);
// New point
double pX = x + rX;
double pY = y + rY;
double pZ = z + rZ;
if (degree > 2D * Math.PI) {
degree = 0D;
} else {
degree = degree + 0.2D;
}
if (pY > 2D) {
pY = 0D;
} else {
pY = pY + 0.02D;
}
}
I'm attempting to implement a curve interesection algorithm known as bezier clipping, which is described in a section towards the end of this article (though the article calls it "fat line clipping"). I've been following through the article and source code of the example (available here).
Note: Additional sources include this paper. More will be posted if I can find them.
A central part of this algorithm is calculating a "distance function" between curve1 and a "baseline" of curve2 (which is a line from one end point of curve2 to another). So I'd have something to compare my results to, I used the curves from the source code of the first example. I managed to replicate the shape of the distance function from the example, but the distance location of the function was off. Upon trying another curve, the distance function was nowhere near the other two curves, despite both clearly intersecting. I might be naive to the workings of this algorithm, but I think that would result in no intersection being detected.
From what I understand (which could quite possibly be wrong), the process of defining the distance function involves expressing the baseline of curve 2 in the form xa + yb + c = 0, where a2 + b2 = 1. The coefficients were obtained by rearranging the terms of the line in the form y = ux + v, where u is equal to the slope, and x and y are any points on the baseline. The formula can be rearranged to give v: v = y - ux. Rearranging the formula again, we obtain -u*x + 1*y - v = 0, where a = -u, b = 1, and c = -v. To assure the condition a2 + b2 = 1, the coefficients are divided by a scalar of Math.sqrt(uu + 1). This representation of the line is then substituted into the function of the other curve (the one the baseline isn't associated with) to get the distance function. This distance function is represented as a bezier curve, with yi = aPi x + b*Pi y + c and xi = (1 - t)x1 + tx2, where t is equal to 0, 1/3, 2/3, and 3m x1 and x2 are the endpoints of the baseline, and Pi are the control points of the curve1.
Below are a few cuts of the source code of the example program (written in the language processing) involved with calculating the distance function, which, oddly, uses a slightly different approach to the above paragraph for calculating the alternative representation of the baseline.
/**
* Set up four points, to form a cubic curve, and a static curve that is used for intersection checks
*/
void setupPoints()
{
points = new Point[4];
points[0] = new Point(85,30);
points[1] = new Point(180,50);
points[2] = new Point(30,155);
points[3] = new Point(130,160);
curve = new Bezier3(175,25, 55,40, 140,140, 85,210);
curve.setShowControlPoints(false);
}
...
flcurve = new Bezier3(points[0].getX(), points[0].getY(),
points[1].getX(), points[1].getY(),
points[2].getX(), points[2].getY(),
points[3].getX(), points[3].getY());
...
void drawClipping()
{
double[] bounds = flcurve.getBoundingBox();
// get the distances from C1's baseline to the two other lines
Point p0 = flcurve.points[0];
// offset distances from baseline
double dx = p0.x - bounds[0];
double dy = p0.y - bounds[1];
double d1 = sqrt(dx*dx+dy*dy);
dx = p0.x - bounds[2];
dy = p0.y - bounds[3];
double d2 = sqrt(dx*dx+dy*dy);
...
double a, b, c;
a = dy / dx;
b = -1;
c = -(a * flcurve.points[0].x - flcurve.points[0].y);
// normalize so that a² + b² = 1
double scale = sqrt(a*a+b*b);
a /= scale; b /= scale; c /= scale;
// set up the coefficients for the Bernstein polynomial that
// describes the distance from curve 2 to curve 1's baseline
double[] coeff = new double[4];
for(int i=0; i<4; i++) { coeff[i] = a*curve.points[i].x + b*curve.points[i].y + c; }
double[] vals = new double[4];
for(int i=0; i<4; i++) { vals[i] = computeCubicBaseValue(i*(1/3), coeff[0], coeff[1], coeff[2], coeff[3]); }
translate(0,100);
...
// draw the distance Bezier function
double range = 200;
for(float t = 0; t<1.0; t+=1.0/range) {
double y = computeCubicBaseValue(t, coeff[0], coeff[1], coeff[2], coeff[3]);
params.drawPoint(t*range, y, 0,0,0,255); }
...
translate(0,-100);
}
...
/**
* compute the value for the cubic bezier function at time=t
*/
double computeCubicBaseValue(double t, double a, double b, double c, double d) {
double mt = 1-t;
return mt*mt*mt*a + 3*mt*mt*t*b + 3*mt*t*t*c + t*t*t*d; }
And here is the class (an extension of javax.swing.JPanel) I wrote to recreate the above code:
package bezierclippingdemo2;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class ReplicateBezierClippingPanel extends JPanel {
CubicCurveExtended curve1, curve2;
public ReplicateBezierClippingPanel(CubicCurveExtended curve1, CubicCurveExtended curve2) {
this.curve1 = curve1;
this.curve2 = curve2;
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(1));
g2d.setColor(Color.black);
drawCurve1(g2d);
drawCurve2(g2d);
drawDistanceFunction(g2d);
}
public void drawCurve1(Graphics2D g2d) {
double range = 200;
double t = 0;
double prevx = curve1.x1*(1 - t)*(1 - t)*(1 - t) + 3*curve1.ctrlx1*(1 - t)*(1 - t)*t + 3*curve1.ctrlx2*(1 - t)*t*t + curve1.x2*t*t*t;
double prevy = curve1.y1*(1 - t)*(1 - t)*(1 - t) + 3*curve1.ctrly1*(1 - t)*(1 - t)*t + 3*curve1.ctrly2*(1 - t)*t*t + curve1.y2*t*t*t;
for(t += 1.0/range; t < 1.0; t += 1.0/range) {
double x = curve1.x1*(1 - t)*(1 - t)*(1 - t) + 3*curve1.ctrlx1*(1 - t)*(1 - t)*t + 3*curve1.ctrlx2*(1 - t)*t*t + curve1.x2*t*t*t;
double y = curve1.y1*(1 - t)*(1 - t)*(1 - t) + 3*curve1.ctrly1*(1 - t)*(1 - t)*t + 3*curve1.ctrly2*(1 - t)*t*t + curve1.y2*t*t*t;
g2d.draw(new LineExtended(prevx, prevy, x, y));
prevx = x;
prevy = y;
}
}
public void drawCurve2(Graphics2D g2d) {
double range = 200;
double t = 0;
double prevx = curve2.x1*(1 - t)*(1 - t)*(1 - t) + 3*curve2.ctrlx1*(1 - t)*(1 - t)*t + 3*curve2.ctrlx2*(1 - t)*t*t + curve2.x2*t*t*t;
double prevy = curve2.y1*(1 - t)*(1 - t)*(1 - t) + 3*curve2.ctrly1*(1 - t)*(1 - t)*t + 3*curve2.ctrly2*(1 - t)*t*t + curve2.y2*t*t*t;
for(t += 1.0/range; t < 1.0; t += 1.0/range) {
double x = curve2.x1*(1 - t)*(1 - t)*(1 - t) + 3*curve2.ctrlx1*(1 - t)*(1 - t)*t + 3*curve2.ctrlx2*(1 - t)*t*t + curve2.x2*t*t*t;
double y = curve2.y1*(1 - t)*(1 - t)*(1 - t) + 3*curve2.ctrly1*(1 - t)*(1 - t)*t + 3*curve2.ctrly2*(1 - t)*t*t + curve2.y2*t*t*t;
g2d.draw(new LineExtended(prevx, prevy, x, y));
prevx = x;
prevy = y;
}
}
public void drawDistanceFunction(Graphics2D g2d) {
double a = (curve1.y2 - curve1.y1)/(curve1.x2 - curve1.x1);
double b = -1;
double c = -(a*curve1.x1 - curve1.y1);
double scale = Math.sqrt(a*a + b*b);
a /= scale;
b /= scale;
c /= scale;
double y1 = a*curve2.x1 + b*curve2.y1 + c;
double y2 = a*curve2.ctrlx1 + b*curve2.ctrly1 + c;
double y3 = a*curve2.ctrlx1 + b*curve2.ctrly2 + c;
double y4 = a*curve2.x2 + b*curve2.y2 + c;
double range = 200;
double t = 0;
double prevx = t*range;
double prevy = (1 - t)*(1 - t)*(1 - t)*y1 + 3*(1 - t)*(1 - t)*t*y2 + 3*(1 - t)*t*t*y3 + t*t*t*y4;
for(t += 1.0/range; t < 1.0; t += 1.0/range) {
double x = t*range;
double y = (1 - t)*(1 - t)*(1 - t)*y1 + 3*(1 - t)*(1 - t)*t*y2 + 3*(1 - t)*t*t*y3 + t*t*t*y4;
g2d.draw(new LineExtended(prevx, prevy, x, y));
prevx = x;
prevy = y;
}
}
}
Where CubicCurveExtended and LineExtended are minor extensions of java.awt.geom.CubicCurve2D.Double and java.awt.geom.Line2D.Double. Before the curves are passed into the constructor, the curves are rotated uniformly so curve1's endpoints are level, resulting in a slope of zero for the baseline.
For an input of (485, 430, 580, 60, 430, 115, 530, 160) for curve 1 and (575, 25, 455, 60, 541, 140, 486, 210) for curve2 (keep in mind that these values are rotated by the negative angle between the endpoints of curve1), the result is shown below (the distance function is the relatively smooth looking curve off in the distance):
I'm really not sure what I got wrong. The y values seem to be arranged in the right pattern, but are distant from the two curves it's based on. I realize it's possible I have the x values might be arranged at intervals along the curve rather than the baseline, but the y values are what I'm really confused about. If someone can take a look at this and explain what I got wrong, I'd really appreciate it. Thanks for taking the time to read this rather lengthy question. If more details are needed, feel free to tell me in comments.
Update: I've tested the representation of the line I've calculated. The ax + by + c = 0 representation apparently still represents the same line, as I can still plug in x1 and get y1. Additionally, for any two coordinate pairs plugged into the function, f(x, y) = 0 holds. Furthermore, I've found both the representation described in the article and the one actually used in the source code interchangeably represent the same line. From all this, I can assume the problem doesn't lie in calculating the line. An additional point of interest
Your distance function should not necessarily be anywhere near your two original curves: It's using a completely different coordinate system, i.e. t vs D, as opposed to your original curves using x and y. [edit] i.e. t only goes up to 1.0, and measures how far along, as a ratio of the total length, you are along your curve, and D measuring the distance your curve2 is from curve1's baseline.
Also, when you say ""distance function" between curve1 and a "baseline" of curve2" I think you've mixed up curve1 and curve2 here as in your code you are clearly using the baseline of curve1.
Also the algorithm assumes that "every Bézier curve is fully contained by the polygon that connects all the start/control/end points, known as its "convex hull"" which [edit] in your case for curve1 is a triangle, where the control point for the second starting value is not a vertex. I'm not sure how this affects the algorithm though.
Otherwise, it looks like your distance calculations are fine (although you could really do with optimising things a bit :) ).
I need to create a class which calculates the distance between two points. I am stuck and I am a total beginner. Here are my classes:
package org.totalbeginner.tutorial;
public class Point {
public double x;
public double y;
Point(double xcoord, double ycoord){
this.x = xcoord;
this.y = ycoord;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}
The second class.
package org.totalbeginner.tutorial;
public class Line {
double x;
double y;
Point p1 = new Point(2.0,2.0);
Point p2 = new Point(4.0,4.0);
Point mp = new Point(x,y);
public void midpoint() {
x = (p1.getX() + p2.getX()) / 2;
y = (p1.getY() + p2.getY()) / 2;
}
}
I am not sure how to get a point object (the middle point) between both defined points.
I can create point objects but I am not sure how to return a point object through my midpoint() method that lies between those two point objects.
The distance between two points (x1,y1) and (x2,y2) on a flat surface is:
____________________
/ 2 2
\/ (y2-y1) + (x2-x1)
But, if all you want is the midpoint of your two points, you should change your midpoint function to:
public Point midpoint (Point p1, Point p2) {
return new Point ((p1.getX() + p2.getX()) / 2, (p1.getY() + p2.getY()) / 2);
}
This will return a brand new point object with the points set to the middle of the given two points (without having to concern yourself with any other math). And, since your second class is a line, you only need the two end points to describe it, so I'd make some minor changes.
First Point.java:
class Point {
double x, y;
Point (double xcoord, double ycoord) {
this.x = xcoord;
this.y = ycoord;
}
public double getX() { return x; }
public double getY() { return y; }
}
Then Line.java:
public class Line {
Point p1, p2;
Line (Point point1, Point point2) {
this.p1 = point1;
this.p2 = point2;
}
public Point midpoint() {
return new Point ((p1.getX()+p2.getX())/2, (p1.getY()+p2.getY())/2);
}
public double abstand() {
return Math.sqrt(
(p1.getX() - p2.getX()) * (p1.getX() - p2.getX()) +
(p1.getY() - p2.getY()) * (p1.getY() - p2.getY())
);
}
static public void main (String args[]) {
Line s = new Line (new Point(2.0, 2.0), new Point(5.0, 6.0));
Point mp = s.midpoint();
System.out.println ("Midpoint = (" + mp.getX() + "," + mp.getY() + ")");
double as = s.abstand();
System.out.println ("Length = " + as);
}
}
These two files, when compiled and run with the endpoints 2,2 and 5,6 (the hypotenuse of a classic 3/4/5 right-angled triangle), generate the correct:
Midpoint = (3.5,4.0)
Length = 5.0
Simple Pythag... root(dx^2 + dy^2)
Math.sqrt(Math.pow((p2.getX() - p1.getX()), 2) + Math.pow((p2.getY() - p1.getY()), 2))
X
+
|\
| \
a| \c
| \
| \
+-----+
b Y
Imagine X and Y are your points on a flat surface. Then a is X.y - Y.y and b is Y.x - X.x . The length of c is their distance, and is the length of the hypotenuse of that triangle. It is calculated using
sqrt(a^2 + b^2);
Since you see we are squaring a and b, the sign of them isn't relevant - it will come down to the same. So this method always works, where ever the points lie.
Lookup the Pythagorean theorem
Do you really need the distance, or are you trying to just get the midpoint? Because from your code snippet, it kind of looks like you just want to create a new point that is half-way between two existing points.
If you're really just after the midpoint, you don't really need an entire 2nd class (i.e., 'Line') to accomplish that. Since the thing you are trying to find is also a point, it makes sense to add a constructor to your existing Point class, like so ..
Point(Point a, Point b)
{
x = (a.x + b.x) / 2;
y = (a.y + b.y) / 2;
}
.. then, elsewhere let's say you already have a couple of points you want to use this on, you use the constructor thus:
Point p1 = new Point(2,2);
Point p2 = new Point(4,4);
Point midpoint = new Point(p1, p2);
and if you really want distance between two points, that's not really an attribute of either point, so it makes sense to use a static method for that, like so
public static double distance(Point a, Point b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
}
and back in the calling code, you can use it this way:
Point p1 = new Point(2,2);
Point p2 = new Point(4,4);
System.out.println("Distance between them is " + Point.distance(p1, p2));
You can use a Maths function for this:
public Point midpoint() {
//Calculate the difference between the old and new x/y
double dx = p1.getX() - p2.getX();
double dy = p1.getY() - p2.getY();
double newX = Math.pow(dx, 2D);
double newY = Math.pow(dz, 2D);
return new Point(newX, newZ);
}
Math.pow handles the issues with negative values and etc. For you,
using Math.pow gives you a safe method because it has a lot of checks built inside.
You can use the Pythagorean Theorem, as other said. Here is a visually demostration from the Wolfram Demostration Project.
alt text http://demonstrations.wolfram.com/DistanceBetweenTwoPoints/HTMLImages/index.en/popup_5.jpg
In your second class, it looks like you're trying to set the values of x and y that are used to construct your mp variable. All your formulas are correct, but you need to consider the order that everything is executed. In the code as it is, it's creating the x and y variables, which start out as 0, then the various Points. x and y are still 0, so mp is set to Point(0, 0).
What you probably want to do is change the return type of midpoint to Point, so that when you call that function, you get back a Point. Then you can create a new Point object with the values you calculate. It should look more like this:
public Point midpoint() {
// calculate the middle x and y
double x = (p1.getX() + p2.getX()) / 2;
double y = (p1.getY() + p2.getY()) / 2;
// now make a new Point with those values, and return it
return new Point(x, y);
}