I am trying to construct an equilateral triangle with the following code, but I am not seeing what I would expect to.
I would expect to see a triangle drawn to the stage, but I don't see one.
I think there must be something wrong in terms of the location of the tri sprite on the screen.
public class test_drawing_triangle extends Sprite
{
public function test_drawing_triangle()
{
var tri:Sprite = new Sprite;
var nextx:int;
var nexty:int;
var prevx:int;
var prevy:int;
var angle:Number;
var radius:Number;
var deg:int;
var i:int;
radius = 10;
// tri.x = stage.stageWidth / 2;
tri.y = 50;
tri.graphics.clear();
tri.graphics.beginFill(0x000000, 0.5);
tri.graphics.moveTo(0,0);
for(deg = 0; deg < 360; deg += 120)
{
angle = deg * Math.PI / 180;
nextx = Math.cos(angle) * radius;
nexty = Math.sin(angle) * radius;
tri.graphics.lineTo(nextx, nexty);
}
tri.graphics.endFill();
addChild(tri);
}
}
UPDATE:
I can now see the triangle but it is not filled in.
It seems to have the generally-correct shape, but I would expect for it be 3 sided, rather than 4.
If anyone could take a sec to compile this and look at what I am describing it would really help.
I'm not sure if I understand what you're trying to do, but if you want to have the circles at the corners of the triangle. than you need to change the
tri.graphics.drawCircle(0, 0, 2);
to
tri.graphics.drawCircle(nextx, nexty, 2);
drawCircle takes absolute x,y and doesn't care about the moveTo
EDIT - use this code in place of your loop
deg = 30;
angle = (deg * Math.PI) / 180.0;
nextx = Math.cos(angle) * radius;
nexty = Math.sin(angle) * radius;
(tri.graphics as Graphics).moveTo(nextx, nexty);
for(deg = 150; deg < 420; deg += 120)
{
angle = (deg * Math.PI) / 180.0;
nextx = Math.cos(angle) * radius;
nexty = Math.sin(angle) * radius;
(tri.graphics as Graphics).lineTo(nextx, nexty);
}
This code looks like its drawing three circles centered on the points of your triangle. If that's the case, then replace
tri.graphics.moveTo(nextx, nexty);
tri.graphics.drawCircle(0, 0, 2);
with
tri.graphics.lineTo(nextx, nexty);
If that's not the case, please specify what it is you are seeing so we might have a better idea of what's gone wrong.
Is there are particular reason why you are using angles to draw the triangle?
If I were to do this, I'd simply hard code a unit sized equilateral triangle (defined as three 3d points) once and then use scale and translation operations to put it in the correct size and position.
Related
I'm trying to write a formula to pan the camera enough so that the center point of an object is just visible at the edge of the screen.
So, in other words if the object is out of view to the right, I would change the x and y position of the camera, so that the object is just at the right edge of the screen (without changing camera angle or z co-ordinate).
Can anyone give me any hints how to do this?
I figured out a solution that serves my purpose, but the only way I could do it was by modifying the camera height (which is not exactly what I wanted):
// note: pos is the center of the object that is to appear at edge of screen
// m_position is the 3d position of the camera
// m_plane[] is array of left, right, etc. planes of camera fustrum
void Camera::PanTo(const Vector3D& pos)
{
int n;
Vector3D vectorNearest;
for (n = 0; n < NUM_PLANES; n++)
{
if (m_plane[n].GetDistance(pos) < 0)
{
m_plane[n].Normalize();
vectorNearest += m_plane[n].GetVectorNearest(pos);
}
}
m_posDesire.m[IX_X] = m_position.m[IX_X] + vectorNearest.m[IX_X];
m_posDesire.m[IX_Y] = m_position.m[IX_Y] + vectorNearest.m[IX_Y];
m_posDesire.m[IX_Z] = m_position.m[IX_Z] + vectorNearest.m[IX_Z];
}
// This is the definition of the Plane class:
class Plane
{
public:
void Normalize()
{
float lenInv = 1.0f/sqrtf(m_a*m_a + m_b*m_b + m_c*m_c);
m_a *= lenInv;
m_b *= lenInv;
m_c *= lenInv;
m_d *= lenInv;
}
float GetDistance(const Vector3D& pos) const
{
return m_a*pos.m[IX_X] + m_b*pos.m[IX_Y] +
m_c*pos.m[IX_Z] + m_d;
}
Vector3D GetVectorNearest(const Vector3D& pos) const
{
Vector3D normal(m_a, m_b, m_c);
float posDotNormal = pos.dotProduct(normal);
Vector3D nearest = normal*(m_d+posDotNormal);
return nearest;
}
float m_a, m_b, m_c, m_d;
};
I have figured out how to make a circle move randomly, but now I want there to be 100 circles, but can't figure out how to add them, HELP!
float my_num = 10;
float n = random(5, 60);
void setup() {
size(500, 500);
background(0);
fill(255);
noStroke();
smooth();
rectMode(CENTER);
}
void draw() {
background(0);
translate(width * noise(my_num + 80), height * noise(my_num + 100));
rotate(10 * noise(my_num + 40));
ellipse(n, n, n, n);
my_num = my_num + 0.02;
}
Sounds like you should create a Circle class that contains the position, size, color, etc of a circle.
Then create an ArrayList or array that contains 100 Circles, and loop through them whenever you want to update or draw those circles.
Recommended reading: http://staticvoidgames.com/tutorials/objects/fireworks
I am using Canvas in QML to draw rotating Rectangle with OpenGL. Here is the code:
//...
property variant points: []
onPointsChanged:{
canvas.requestPaint();
}
//...
Canvas{
//...
onPaint:{
var ctx = canvas.getContext('2d')
ctx.clearRect(0,0, width, height);
ctx.beginPath()
ctx.strokeStyle = 'red'
ctx.lineWidth = 3
for(var i = 0; i < points.length; i++){
var p1 = convertPoint(points[i])
if(i == 0){
ctx.moveTo(p1.x, p1.y)
continue
}
ctx.lineTo(p1.x, p1.y)
}
ctx.stroke()
ctx.restore()
}
function convertPoint(p){
var x = p.x * width;
var y = p.y * height;
return Qt.point(x,y);
}
}
There are 4 points counted in c++ code and sent to qml every 30ms. Problem is that this paint operation takes 50% of CPU usage when compile under MinGW and when compile under MSVC2010 operation takes 17% of CPU, which is still a lot. It is some bug or what is bad?
Consider using the new scene graph classes instead of Canvas if performance is critical. In particular, you'd be interested in the QSGGeometryNode class. If you prefer the simplicity of the Canvas API, you have to be aware of how it's best used. This article gives you some insight into that.
Edit: I've also found improvements on embedded hardware (specifically the Raspberry Pi) using the QQuickPaintedItem class in certain cases.
I am zooming an image on a label using QGraphicsView. But when I zoom out I want to set a specific limit for the zoom out. I am using the following code
scene = new QGraphicsScene(this);
view = new QGraphicsView(label);
QPixmap pix("/root/Image);
Scene->addPixmap(pixmap);
view->setScene(scene);
view->setDragMode(QGraphicsView::scrollHandDrag);
In the slot of wheel event
void MainWindow::wheelEvent(QWheelEvent *ZoomEvent)
{
view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
double scaleFactor = 1.15;
if(ZoomEvent->delta() >0)
{
view->scale(scaleFactor,scaleFactor);
}
else
{
view->scale(1/scaleFactor,1/scaleFactor);
}
}
I want that the image should not zoom out after a certain extent. What should I do?
I tried setting the minimum size for QGraphicsView but that didn't help.
Thank You :)
Maybe something like this would help:
void MainWindow::wheelEvent(QWheelEvent *ZoomEvent)
{
view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
static const double scaleFactor = 1.15;
static double currentScale = 1.0; // stores the current scale value.
static const double scaleMin = .1; // defines the min scale limit.
if(ZoomEvent->delta() > 0) {
view->scale(scaleFactor, scaleFactor);
currentScale *= scaleFactor;
} else if (currentScale > scaleMin) {
view->scale(1 / scaleFactor, 1 / scaleFactor);
currentScale /= scaleFactor;
}
}
The idea, as you can see, is caching the current scale factor and do not zoom out in case of it smaller than some limit.
Here is one more implementation idea in which the current zoom factor is obtained from the transformation matrix for the view:
void View::wheelEvent(QWheelEvent *event) {
const qreal detail = QStyleOptionGraphicsItem::levelOfDetailFromTransform(transform());
const qreal factor = 1.1;
if ((detail < 10) && (event->angleDelta().y() > 0)) scale(factor, factor);
if ((detail > 0.1) && (event->angleDelta().y() < 0)) scale((1 / factor), (1 / factor));
}
Another way to solve the problem:
void GraphWidget::wheelEvent(QWheelEvent *event)
{
int scaleFactor = pow((double)2, - event->delta() / 240.0);
qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
if (factor < 0.5 || factor > 20)
return;
scale(scaleFactor, scaleFactor);
}
I just cannot get the png image to display, I check that it loads correctly which is does but nothing is displayed on my blank canvases. The third one is meant to display an image. Can someone please have a quick look? Thanks.
QImage * QI = new QImage;
bool Check = QI->load("test.png");
QGraphicsPixmapItem * QII = new QGraphicsPixmapItem(QPixmap::fromImage(*QI));
QRect ImagePanelArea1(0, MenuBarHeight,
ScreenWidth / 3, (ScreenHeight / 2) - MenuBarHeight);
QRect ImagePanelArea2(ScreenWidth / 3, MenuBarHeight,
ScreenWidth / 3, (ScreenHeight / 2) - MenuBarHeight);
QRect ImagePanelArea3((ScreenWidth / 3) * 2, MenuBarHeight,
ScreenWidth / 3, (ScreenHeight / 2) - MenuBarHeight);
QGraphicsScene * QGS1 = new QGraphicsScene(ImagePanelArea1, this);
QGraphicsScene * QGS2 = new QGraphicsScene(ImagePanelArea2, this);
QGraphicsScene * QGS3 = new QGraphicsScene(ImagePanelArea3, this);
QGS3->addItem(QII);
QGraphicsView * QGV1 = new QGraphicsView(QGS1, this);
QGV1->setGeometry(ImagePanelArea1);
QGV1->show();
QGraphicsView * QGV2 = new QGraphicsView(QGS2, this);
QGV2->setGeometry(ImagePanelArea2);
QGV2->show();
QGraphicsView * QGV3 = new QGraphicsView(QGS3, this);
QGV3->setGeometry(ImagePanelArea3); QGV3->show();
Are you sure that you item is not outside of your scene QGS3?
QII is at the position (0;0). The QRect of your scene is defined between the point ((ScreenWidth / 3) * 2, MenuBarHeight) and the point (ScreenWidth / 3, (ScreenHeight / 2) - MenuBarHeight).
So, if your image is less larger than (ScreenWidth / 3) * 2, your item will be not visible.